[bash] 프로세스 종료 코드를 기반으로 종료 쉘 스크립트

많은 명령을 실행하는 쉘 스크립트가 있습니다. 명령이 0이 아닌 종료 코드로 종료되면 쉘 스크립트를 종료하려면 어떻게합니까?



답변

각 명령 후에는 종료 코드를 $?변수 에서 찾을 수 있으므로 다음과 같이됩니다.

ls -al file.ext
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi

$?코드에서 파이프의 마지막 요소에 대한 리턴 코드 만 제공 하므로 파이프 된 명령에주의해야합니다 .

ls -al file.ext | sed 's/^/xx: /"

파일이 존재하지 않으면 오류 코드를 반환하지 않습니다. sed 파이프 라인 일부가 실제로 작동하기 때문에 0을 반환 함).

bash쉘 실제로,이 경우에 도움이 될 수있는 배열을 제공되는 것 PIPESTATUS. 이 배열에는 각 파이프 라인 구성 요소마다 하나의 요소가 있으며 ${PIPESTATUS[0]}다음 과 같이 개별적으로 액세스 할 수 있습니다 .

pax> false | true ; echo ${PIPESTATUS[0]}
1

이것은 false전체 파이프 라인이 아니라 명령 의 결과를 가져옵니다 . 적합하다고 생각되면 전체 목록을 처리 할 수도 있습니다.

pax> false | true | false; echo ${PIPESTATUS[*]}
1 0 1

파이프 라인에서 가장 큰 오류 코드를 얻으려면 다음과 같이 사용할 수 있습니다.

true | true | false | true | false
rcs=${PIPESTATUS[*]}; rc=0; for i in ${rcs}; do rc=$(($i > $rc ? $i : $rc)); done
echo $rc

이것은 각 PIPESTATUS요소를 차례로 통과 rc하여 이전 rc값 보다 큰 경우 저장합니다 .


답변

$?로 작업하려면 $?부터 각 명령 후에 확인해야합니다. 각 명령이 종료 된 후 업데이트됩니다. 즉, 파이프 라인을 실행하면 파이프 라인에서 마지막 프로세스의 종료 코드 만 가져옵니다.

다른 접근 방법은 다음과 같습니다.

set -e
set -o pipefail

이것을 쉘 스크립트의 맨 위에두면 bash가 이것을 처리하는 것처럼 보입니다. 이전 포스터에서 언급했듯이 “set -e”는 간단한 명령에서 bash가 오류와 함께 종료되도록합니다. “set -o pipefail”은 파이프 라인의 모든 명령에서 bash가 오류와 함께 종료되도록합니다.

이 문제에 대한 자세한 내용은 여기 또는 여기 를 참조 하십시오 . 여기 에 내장 된 bash 매뉴얼 섹션이 있습니다.


답변

set -e“이 가장 쉬운 방법 일 것입니다. 프로그램의 명령 앞에 넣으십시오.


답변

매개 변수없이 bash에서 exit를 호출하면 마지막 명령의 종료 코드가 반환됩니다. OR과 결합하여 bash는 이전 명령이 실패한 경우에만 exit를 호출해야합니다. 그러나 나는 이것을 테스트하지 않았습니다.

command1 || 출구;
command2 || 출구;

Bash는 또한 마지막 명령의 종료 코드를 변수 $?에 저장합니다.


답변

[ $? -eq 0 ] || exit $?; # exit for none-zero return code


답변

http://cfaj.freeshell.org/shell/cus-faq-2.html#11

  1. 어떻게의 종료 코드를받을 수 있나요 cmd1인을cmd1|cmd2

    첫째, cmd1종료 코드는 0이 아닐 수 있으며 여전히 오류를 의미하지는 않습니다. 예를 들어

    cmd | head -1

    종료 상태가 141 (또는 ksh93 인 269) 인 경우 SIGPIPE 신호에 의해 중단
    cmd1되었기 때문입니다.cmdhead -1 한 줄을 읽은 후 종료 입니다.

    파이프 라인 요소의 종료 상태를 알려면
    cmd1 | cmd2 | cmd3

    ㅏ. zsh로 :

    종료 코드는 pipestatus 특수 배열에 제공됩니다.
    cmd1종료 코드는 $pipestatus[1]이고 cmd3종료 코드는
    $pipestatus[3]이므로 $?항상와 같습니다
    $pipestatus[-1].

    비. bash와 함께 :

    종료 코드는 PIPESTATUS특수 배열 로 제공됩니다 .
    cmd1종료 코드는 ${PIPESTATUS[0]}이고 cmd3종료 코드는
    ${PIPESTATUS[2]}이므로 $?항상와 같습니다
    ${PIPESTATUS: -1}.

    자세한 내용은 다음 링크를 참조하십시오 .


답변

bash의 경우 :

# this will trap any errors or commands with non-zero exit status
# by calling function catch_errors()
trap catch_errors ERR;

#
# ... the rest of the script goes here
#  

function catch_errors() {
   # do whatever on errors
   # 
   #
   echo "script aborted, because of errors";
   exit 0;
}