Как я могу отличить "подстановку команд" от "подоболочки" внутри скрипта?

Мне нужно различать два случая: (… subshell…) и $( … подстановка команд…)

У меня уже есть следующая функция, которая различает запуск в подстановке команд или подоболочку и запуск непосредственно в сценарии.

#!/bin/bash
set -e

function setMyPid() {
    myPid="$(bash -c 'echo $PPID')"
}

function echoScriptRunWay() {
    local myPid
    setMyPid
    if [[ $myPid == $$ ]]; then
        echo "function run directly in the script"
    else
        echo "function run from subshell or substitution"
    fi
}

echoScriptRunWay
echo "$(echoScriptRunWay)"
( echoScriptRunWay; )

Пример вывода:

function run directly in the script
function run from subshell or substitution
function run from subshell or substitution

Желаемый вывод

Но я хочу обновить код, чтобы он различал подстановку команд и подоболочку. Я хочу, чтобы это произвело вывод:

function run directly in the script
function run from substitution
function run from subshell

PS Мне нужно дифференцировать эти случаи, потому что Bash имеет другое поведение для встроенного trap команда при запуске в подстановке команд и в подоболочке.

PPS я забочусь о echoScriptRunWay | cat командовать также. Но это новый вопрос для меня, который я создал здесь.

1 ответ

Я не думаю, что можно надежно проверить, выполняется ли команда внутри подстановки команд.

Вы можете проверить, если stdout отличается от stdout основного сценария, и если он это делает, смело сделать вывод, что он мог быть перенаправлен. Например

samefd() {
    # Test if the passed file descriptors share the same inode
    perl -MPOSIX -e "exit 1 unless (fstat($1))[1] == (fstat($2))[1]"
}

exec {mainstdout}>&1

whereami() {
    if ((BASHPID == $$))
    then
        echo "In parent shell."
    elif samefd 1 $mainstdout
    then
        echo "In subshell."
    else
        echo "In command substitution (I guess so)."
    fi
}

whereami
(whereami)
echo $(whereami)
Другие вопросы по тегам