서브쉘에서 -e 설정

서브쉘에서 -e 설정

set -e서브쉘에 미치는 영향은 상단 쉘과 동일하다고 생각합니다 . 분명히 이것은 사실이 아닙니다. 이것:

(
  set -e
  false 
  true
) || echo false1


bash -ec '
  set -e
  false 
  true
' || echo false2


bash <<EOF || echo false3
  set -e
  false 
  true
EOF

bash <<EOF || echo false4
  false 
  true
EOF

bash <<EOF || echo false5
  false  &&
  true
EOF

인쇄

false2
false3
false5

이건 어디서 녹음됐나요? 모든 명령을 연결하지 않고 &&(또는 각 명령 후에 아무 작업도 수행하지 않고 || exit $?) 오류가 발생하면서 서브쉘을 종료할 수 있습니까?

편집하다:

내 구체적인 사용 사례는 다음과 같습니다.

set -e
  # ...
status=0
( false; true ) || status=$?
report_code $status
return $status

서브셸의 내용은 실제 코드입니다. 이것의 문제는 항상 상태를 0으로 설정하고 외부 설정으로 인해 -e를 바꾸면 || 불필요한 오류 종료가 발생한다는 것입니다.;

나는 다음을 사용하여 문제를 해결했습니다.

set -e
  # ...
set +e
( false; true ); status=$?
set -e
report_code $status
return $status

이 작업을 수행할 필요가 없었으면 좋겠지만 모든 일반 쉘은 execed-subshel과 just-forked-subshel의 이분법을 보여주는 것 같습니다.

#!/bin/sh

echo FORK\'D:
export SH
for SH in dash bash ksh zsh; do
    $SH -c 'st=0; ( set -e; false; true ) || st=$?; printf "%s\t%s\n" $SH  $st; '
done

echo EXEC\'D:
for SH in dash bash ksh zsh; do
    $SH -c 'st=0; '$SH' -c " set -e; false; true " || st=$?; printf "%s\t%s\n" $SH $st; '
done

산출:

FORK'D:
dash    0
bash    0
ksh 0
zsh 0
EXEC'D:
dash    1
bash    1
ksh 1
zsh 1

답변1

관찰하다:

$ ( set -e; false ; true ) || echo false1
$ ( set -e; false ; true ) ; echo code=$?
code=1

반품:

$ ( set -e; false ; true; echo inside=$? ) || echo false1
inside=0

분명히 서브쉘 뒤에 가 있으면 ||명령 에 도달할 때 set -e서브쉘이 종료되지 않습니다 . false대신 서브쉘이 계속해서 실행됩니다 true(and echo inside=$?).

set -e일반적으로 발견되지 않은 오류에 대해서만 존재한다는 아이디어 입니다. 여기서, 외부 서브쉘의 존재는 ||서브쉘 내부의 오류가 "잡혀" 있으므로 set -epost-exit 가 발생하지 않는다는 것을 쉘에 알려주는 것 같습니다 false.

set -e놀라운 행동이 많이 있습니다. 바라보다"왜 set -e가 내가 기대하는 대로 작동하지 않나요?"

문서

위의 동작은 다음 문서에 암시되어 있습니다 man bash.

-e

파이프(단일 단순 명령으로 구성될 수 있음), 목록 또는 복합 명령(위의 SHELL GRAMMAR 참조)이 0이 아닌 상태로 종료되면 즉시 종료합니다. 실패한 명령이 쉘인 경우 쉘은 종료되지 않습니다.명령 목록 부분은 while 또는 Until 키워드 바로 뒤에 나오고, 테스트 부분은 if 또는 elif 예약어 뒤에 옵니다.&& 또는 || 내에서 실행되는 명령의 일부 목록마지막 && 또는 || 뒤의 마지막 명령 또는 !로 반전된 명령의 반환 값을 제외한 파이프라인의 모든 명령. -e가 생략되었을 때 명령이 실패했기 때문에 하위 쉘 외부의 복합 명령이 0이 아닌 상태를 반환하는 경우 쉘이 종료되지 않습니다. ERR 트랩이 설정되면 쉘이 종료되기 전에 실행됩니다. 이 옵션은 셸 환경과 각 하위 셸 환경(위의 명령 실행 환경 참조)에 개별적으로 적용되며 하위 셸의 모든 명령을 실행하기 전에 하위 셸이 종료될 수 있습니다. [강조하다. ]

관련 정보