`set -e`를 사용하는 Bash 스크립트는 `... && ...` 명령에서 중지되지 않습니다.

`set -e`를 사용하는 Bash 스크립트는 `... && ...` 명령에서 중지되지 않습니다.

나는 ~하곤 set -e했다첫 번째 오류 시 bash 스크립트 중지.

다음과 함께 명령을 사용하지 않는 한 모두 정상적으로 작동합니다 &&.

$ cat script
set -e
cd not_existing_dir && echo 123
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
I'm running! =P
$

다음과 비교:

$ cat script
set -e
cd not_existing_dir
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
$

첫 번째 예에서는 여전히 echo 가 발생 I'm running!하지만 두 번째 예에서는 그렇지 않습니다. 왜 그들은 다르게 행동합니까?

UPD. 비슷한 질문:https://stackoverflow.com/questions/6930295/set-e-and-short-tests

답변1

이는 문서화된 동작입니다. 그만큼bash(1) 매뉴얼 페이지라고 말한다.set -e,

while실패한 명령이 또는 키워드 바로 다음의 명령 목록의 일부이거나 또는 예약어 until다음의 테스트의 일부인 경우 쉘은 종료되지 않습니다.ifelif&&또는 ||목록 에서 실행되는 명령의 일부 마지막 &&또는 다음 명령을 제외하고||, 파이프라인의 모든 명령(마지막 명령 제외) 또는 명령의 반환 값이 로 반전되는 경우 !.
[강조가 추가되었습니다.]

그리고POSIX쉘 명령 언어사양 이것이 올바른 동작인지 확인합니다.

, , 또는 예약어 뒤에 오는 복합 목록, 예약어로 시작하는 파이프라인 또는 마지막이 아닌 AND-OR 목록의 명령을 실행하는 경우 설정 -e이 무시됩니다 .whileuntilifelif!

그리고섹션 2.9.3기울기해당 문서의 정의

&&AND-OR 목록은 " " 및 " ||" 연산자로 구분된 하나 이상의 파이프라인 시퀀스입니다 .

답변2

set -e옵션은 일부 상황에서는 효과가 없으며 이는 표준 동작이며 POSIX 호환 셸에서 이식 가능합니다.


실패한 명령은 파이프라인의 일부입니다.

false | true; echo printed

인쇄됩니다 printed.

그리고 파이프라인 자체의 실패만 고려됩니다.

true | false; echo 'not printed'

아무것도 인쇄하지 않습니다.


실패한 명령은 while, until, if, elif예약어 뒤의 복합 목록, 예약어로 시작하는 파이프라인 또는 마지막 항목을 제외한 목록 의 !일부인 명령 에서 실행됩니다.&&||

false || true; echo printed

마지막 명령이 실패하면 여전히 영향을 받습니다 set -e.

true && false; echo 'not printed'

그만큼서브쉘복합 명령에서 실패합니다.

(false; echo 'not printed') | cat -; echo printed

답변3

내 추측은 if-then 조건이 전체적으로 true로 평가된다는 것입니다.

나는 노력했다

set -e
if cd not_existing_dir
then  echo 123
fi
echo "I'm running! =P"

누가 주는가

-bash: cd: not_existing_dir: No such file or directory
I'm running! =P

오류 코드는 if 조건에 의해 포착되므로 bash는 실행 종료를 트리거하지 않습니다.

관련 정보