명령이 성공하면 bash 스크립트를 종료합니다.

명령이 성공하면 bash 스크립트를 종료합니다.

일반적으로 다음과 같은 간단한 연기 테스트 스크립트가 있습니다.

set -e

run-command
run-other-command

echo ok

이는 명령이 성공할 것으로 예상할 때 완벽하게 작동합니다. 실패하면 set -e스크립트가 0이 아닌 종료 코드로 일찍 종료됩니다.

그러나 때로는 명령이 실패할 것으로 예상하고 스크립트가 다른 방식으로 종료되기를 원합니다(예: 명령이 코드 0으로 종료되는 경우). 나는 다음과 같이 쓸 수 있다고 생각했습니다.

set -e
run-command-that-succeeds
! run-command-that-fails

그러나 이는 종료 코드를 무시합니다. Bash 매뉴얼 페이지에서는 다음과 같이 설명합니다 set -e.

명령의 반환 값이 !로 부정되면 쉘은 종료되지 않습니다 [...]

유효한 대안은 다음과 같습니다.

set -e
! run-command-that-fails
[[ $? -eq 0 ]]

그리고

set -e
if run-command-that-fails; then
  exit 1
fi

이것이 최선의 옵션입니까, 아니면 명령이 성공할 때 종료하는 것보다 더 관용적인 대안이 있습니까?

답변1

내 테스트에 따르면 이것이 (! run-command-that-fails)해결책입니다. run-command-that-fails서브쉘에서 실행됩니다 .

run-command-that-fails어떤 이유로든 기본 셸에서 실행해야 하는 경우 다른 솔루션이 필요합니다. 나는 그것 { ! run-command-that-fails; }이었다는 것을 알아차렸다.아니요일방 통행.

답변2

set -e완전히 포기하고 다음과 같은 것을 사용하면 더 쉬울 것입니다.

should-fail    && exit 1
should-succeed || exit 1

위 코드에서는 should-fail실패가 예상되며 실패할 경우 스크립트는 0이 아닌 종료 코드로 종료됩니다.

두 번째 작업은 성공할 것으로 예상되지만 그렇지 않으면 스크립트가 종료됩니다.

또는 AND-OR 목록을 일관되게 사용하려면

! should-fail  || exit 1
should-succeed || exit 1 

또는

should-fail      && exit 1
! should-succeed && exit 1

실패할 경우 단순한 것 이상이 필요한 경우에는 exit다음을 사용합니다.

if should-fail; then
    # handle failure in test
    exit 1
fi

if ! should-succeed; then
    # handle failure in test
    exit 1
fi

아시다시피 set -e활성 상태에서는 명령의 종료 상태가 반전되어도 쉘이 종료되지 않습니다 !. 이는 POSIX 요구 사항입니다. 다음 내용은 다음에서 가져온 것입니다.특수 내장 유틸리티에 대한 POSIX 사양set, 나는 강조한다:

, , 예약어 뒤에 -e오는 복합 목록을 실행할 경우에는 이 설정을 무시해야 합니다 .whileuntilifelif!예약어로 시작하는 파이프, 또는 목록의 마지막 명령을 제외한 모든 명령을 AND-OR합니다.

관련 정보