하위 프로세스가 0이 아닌 종료 코드로 종료되면 상위 스크립트가 계속됩니다.

하위 프로세스가 0이 아닌 종료 코드로 종료되면 상위 스크립트가 계속됩니다.

다른 스크립트를 호출하는 스크립트가 있습니다. 하위 스크립트가 실패하면 상위 스크립트도 실패하기를 원합니다.

아래 첨자에는 child_1.sh다음과 같은 내용이 있습니다.

if [ $SOME_BAD_CONDITION ] ; then
  echo "Error message...."
  exit 1
fi

부모에는 다음이 있습니다.

#!/bin/bash
set -e
#...
bash ./child_1.sh
echo "continuing to next step..."
bash ./child_2.sh
bash ./child_3.sh
#...

$SOME_BAD_CONDITION항상 이런 일이 발생하고 스크립트가 오류 메시지와 함께 예상대로 종료되도록 환경을 설정했습니다.하다인쇄하지만 상위 스크립트는 계속됨: "계속..." 메시지를 인쇄하고 다음 스크립트 실행을 시작합니다.

set -e상위 스크립트가 실패하도록 보장하는 0이 아닌 종료 코드가 있는 하위 스크립트가 있는 경우에는 그런 일이 발생하지 않을 것이라고 생각했습니다 . 여기서 내가 뭘 잘못하고 있는지 잘 모르겠습니다 ...

배쉬 버전: 4.2.25


고쳐 쓰다:

나는 에코를 시도합니다 $?:

bash ./child_1.sh
echo $?
echo "continuing to next step..."

출력은 다음과 같습니다.

에러 메시지....
0
다음 단계로 계속하세요...

하위 프로세스의 종료 코드가 상위 프로세스로 이동하지 않는 이유는 무엇입니까?


답변: 원본 코드 조각은 불완전합니다. 이는 exit 1티에 파이프로 연결된 코드 블록 내부에 있습니다. 포스팅을 하려고 합니다깨끗하다, 짧다코드 예제에서는 이것이 얼마나 중요한지 몰랐기 때문에 이를 무시합니다(저는 bash 스크립팅을 처음 접했습니다). 자세한 내용은 내가 게시한 답변을 참조하세요.

답변1

따라서 아래 첨자에 대한 세부 정보를 충분히 게시하지 않은 실수를 범했을 수도 있습니다. 이 질문의 목적을 위해 단순화했지만 아마도 너무 많을 것입니다. 명령문은 로깅으로 파이프되는 exit코드 블록( {및 사이) 내에 숨겨져 있습니다 .}tee

{
  #...
  if [ $SOME_BAD_CONDITION ] ; then
    exit 1
  fi
  #...
} | tee -a $LOGFILE
echo "script ended at $date">>$LOGFILE

내가 이해한 바로는 마지막 스크립트가 0을 반환하기 때문에 이 첨자에서 항상 반환 코드 0을 얻습니다 echo. 좀 조사해서 알아냈어요$파이프라인 상태. 이를 사용하여 스크립트가 종료 코드 1로 종료하려고 할 때 상위 스크립트로 전달되도록 할 수 있었습니다.

{
  #...
} | tee -a $LOGFILE
EXIT_CODE=${PIPESTATUS[0]}
echo "script ended at $date">>$LOGFILE
exit $EXIT_CODE

John의 제안과 결합하여 작동하는 것처럼 보이는 솔루션이 있습니다.

답변2

하위 프로세스가 올바른 0/0이 아닌 종료 코드 규칙으로 종료되고 순차적으로 실행한다는 점을 고려하면 연산자를 사용할 수 있다고 말하고 싶습니다 &&.

#!/bin/bash

./child_1.sh
[[ $? -ne 0 ]] && exit # Exit if non-zero exit code
./child_2.sh
./child_3.sh
./child_4.sh
exit 0

여기서 [[ $? -ne 0 ]] && exit동작은 다음과 같습니다.

if [ $? -ne 0 ]; then # If: last exit code is non-zero
    exit
fi

통화 사이에 할 일이 없다면 다음을 사용할 수도 있습니다...

#!/bin/bash
./child_1.sh && ./child_2.sh && ./child_3.sh && ./child_4
exit $?

운영자는 &&다음과 같이 행동합니다.단락 AND 연산자, 0 종료 코드는 true부울 값과 매우 유사합니다. 체인에서 언제든지 스크립트가 0이 아닌 값으로 종료되면 스크립트가 &&실패하고 후속 스크립트를 호출하면 안 됩니다.

답변3

문제는 아래 첨자에 오류를 던지는 방식에서 비롯된 것 같습니다.

Man set에서 "간단한 명령(위의 SHELL GRAMMAR 참조)이 0이 아닌 상태로 종료되는 경우. 실패한 명령이 while 또는 Until 키워드(테스트의 일부) 바로 다음에 나오는 명령 목록의 일부인 경우 쉘은 종료 if 문에서 && 또는 ||가 목록의 일부이거나 명령의 반환 값이 !"

set -e를 사용하는 대신 Trap 문을 사용하고 오류를 발생시킵니다. (필요하다면 조건부 종료를 사용하세요.

바라보다http://mywiki.wooledge.org/BashFAQ/105

관련 정보