Bash가 명령 대체에 errexit 옵션을 전달하지 않는 이유는 무엇입니까?

Bash가 명령 대체에 errexit 옵션을 전달하지 않는 이유는 무엇입니까?

다음으로 설정된 쉘 옵션set내장하위 쉘(적어도 errexit)에서 상속됩니다. 이는 다음을 통해 증명할 수 있습니다.

set -o errexit

function foo() {
    echo "foo:$BASHPID"
    false
    echo 'after' 
}

echo "main:$BASHPID"
( foo )

그러나 옵션은 상속되지 않은 것 같습니다.명령 대체, Bash 문서에 따르면 하위 쉘이기도 합니다. 증거:

set -o errexit

function foo() {
    echo "foo:$BASHPID"
    false
    echo 'after' 
}

echo "main:$BASHPID"
output=$(foo)
echo "output: $output"

예상 출력:

main:123
output: foo:124

실제 출력:

main:123
output: foo:124
after

예상된 것인가요, 아니면 버그인가요?

답변1

예, 예상됩니다. POSIX 모드가 아닌 경우(예: 로 실행될 때 sh) bash는 errexit기본적으로 명령 대체 내부를 재설정합니다.

errexitbash 4.4 이상에서 명령 대체 내부를 유지하려면 다음을 사용하십시오 .

inherit_errexit

errexit설정된 경우 명령 대체는 하위 쉘 환경에서 옵션을 설정 해제하는 대신 옵션 값을 상속합니다 . 이 옵션은 POSIX 모드가 활성화된 경우 활성화됩니다.

(에서배쉬 매뉴얼.)문서의 또 다른 부분더 명확하게 만들었습니다.

POSIX 모드를 활성화하면 옵션을 설정하는 효과가 있으므로 명령 대체를 실행하기 위해 생성된 하위 쉘은 상위 쉘에서 옵션 inherit_errexit값을 상속합니다 .-e옵션 inherit_errexit이 활성화되지 않으면 Bash는 -e해당 하위 쉘에서 옵션을 지웁니다.

확인하려면:

$ bash -o errexit -c 'echo "$(echo "$SHELLOPTS")"'
braceexpand:hashall:interactive-comments
$ bash -o errexit -O inherit_errexit -c 'echo "$(echo "$SHELLOPTS")"'
braceexpand:errexit:hashall:interactive-comments

bash 4.2 이상에서는 errexit전자에 표시되었지만 여전히 효과적으로 비활성화되었습니다.

$ bash-4.2 -o errexit c 'echo "$(false; echo "$SHELLOPTS")"'
braceexpand:errexit:hashall:interactive-comments
$ bash-4.2 -o posix -o errexit -c 'echo "<$(false; echo "$SHELLOPTS")> $?"'
<> 1

관련 정보