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

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

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

inherit_errexit

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

(에서배쉬 매뉴얼.)문서의 다른 부분더 명확하게 하려면:

inherit_errexitPOSIX 모드를 활성화하면 명령 대체를 수행하기 위해 생성된 하위 쉘이 -e상위 쉘에서 상속되도록 이 옵션을 설정하는 효과가 있습니다 .inherit_errexitBash는 활성화되지 않은 -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

관련 정보