저는 여러 기능을 갖춘 Bash 스크립트를 작성하고 있습니다. 해당 코드를 명시적으로 처리하는 컨텍스트(예: 조건부 if
또는 ||
대안 이전) 를 제외하고 명령이 0이 아닌 종료 코드를 반환하는 경우 스크립트를 종료하고 싶습니다 . 이를 더 쉽게 만들기 위해 스크립트에서 모든 하위 쉘 사용을 제거하고 찾을 수 있는 모든 오류 처리 옵션을 활성화했습니다.
불행하게도 나는 여전히 오류가 억제되는 일반적인 패턴을 접하고 있습니다.
함수의 명령이 0이 아닌 종료 코드를 반환하지만 함수의 마지막 명령이 아니고 함수가 표현식의 첫 번째 부분으로 호출되는 경우 &&
종료 코드는 무시됩니다.
#!/bin/bash
trap 'echo "Error occurred." && exit' ERR
set -o errexit; # -e
set -o errtrace; # -E
set -o pipefail;
first-step-fails() {
# These should be redundant, but are repeated to be certain and clear.
trap 'echo "Error occurred." && exit' ERR
set -o errexit; # -e
set -o errtrace; # -E
set -o pipefail;
false; # exit code 1 (failure)
true; # exit code 0 (success)
echo "A is executed.";
}
first-step-fails && echo "B is executed.";
A is executed.
B is executed.
echo
전화할 줄은 몰랐어요 false
.
&&
표현식에서 함수가 호출되지 않으면 오류가 발생합니다 .
#!/bin/bash
trap 'echo "Error occurred." && exit' ERR
set -o errexit; # -e
set -o errtrace; # -E
set -o pipefail;
first-step-fails() {
# These should be redundant, but are repeated to be certain and clear.
trap 'echo "Error occurred." && exit' ERR
set -o errexit; # -e
set -o errtrace; # -E
set -o pipefail;
false; # exit code 1 (failure)
true; # exit code 0 (success)
echo "A is executed.";
}
first-step-fails ### && echo "B is executed.";
Error occurred.
실패가 함수의 마지막 단계인 경우 오류가 포착되지 않지만 함수는 물론 0이 아닌 종료 상태를 전달하고 외부 echo
.
#!/bin/bash
trap 'echo "Error occurred." && exit' ERR
set -o errexit; # -e
set -o errtrace; # -E
set -o pipefail;
first-step-fails() {
# These should be redundant, but are repeated to be certain and clear.
trap 'echo "Error occurred." && exit' ERR
set -o errexit; # -e
set -o errtrace; # -E
set -o pipefail;
false; # exit code 1 (failure)
### true; # exit code 0 (success)
### echo "A is executed.";
}
first-step-fails && echo "B is executed.";
(no output)
표현식 왼쪽에서 호출된 함수 내에서 호출된 명령이 0이 아닌 종료 상태를 반환할 때 bash 스크립트를 종료하려면 어떻게 해야 합니까 &&
?
저는 macOS(GNU Bash 4.4.23 내장)에서 테스트해 왔지만 Alpine Linux(GNU Bash 4.4.19 패키지)에서도 작동하는 솔루션이 필요합니다.
답변1
나에게는 다음과 같은 설명처럼 보입니다 set -e
.
실패한 명령이 명령의 일부인 경우 쉘은 목록을 종료하지 않습니다... && 또는 || 내에서 실행됩니다.
함수 호출에 모든 명령을 포함하려면 "목록의 && 부분"을 자유롭게 해석하세요. 따라서 함수 내에서 간단한 실패한 명령이라도 &&
체인에서 호출될 때 ERR 트랩을 트리거하지 않습니다.
함수 명령 중 하나가 실패할 때 함수의 명령 실행을 중지해야 하는 경우 한 가지 방법은 해당 명령을 모두 블록으로 연결하는 것입니다.
first-step-fails() {
{
true &&
false &&
true;
} || exit 1
echo "A is executed.";
}
first-step-fails && echo "B is executed.";
...결과가 출력되지 않고 반환 코드는 1입니다.