if 문을 사용하여 종료 상태를 확인하는 방법


255

특정 출력을 에코하기 위해 if 문에서 종료 상태를 확인하는 가장 좋은 방법이 무엇인지 궁금합니다.

나는 그것이 생각

if [ $? -eq 1 ]
then
   echo "blah blah blah"
fi

내가 가진 문제는 exit 문이 if 문 앞에 있다는 것입니다. 종료 코드가 있어야하기 때문입니다. 또한 종료는 분명히 프로그램을 종료하기 때문에 내가 잘못하고 있다는 것을 알고 있습니다.


3
Plaese는 완전한 스크립트 (또는 더 넓은 범위)를 게시합니다. 그렇지 않으면 괜찮아 보입니다.
— RedX

5
두 개의 서로 다른 장소에서 어떤 특정 프로그램의 호출에서 종료 코드를 사용해야하는 경우에, 당신은 그것을 유지하기 위해 필요 -의 라인을 따라 뭔가some_program; rc=$?; if [ ${rc} -eq 1 ] .... fi ; exit ${rc}
— twalberg

답변:


262

실행되는 모든 명령에는 종료 상태가 있습니다.

이 검사는 해당 행이 실행되기 전에 가장 최근에 완료된 명령의 종료 상태를보고 있습니다.

당신이 원하는 경우에 당신의 그 평가 결과가 true 때 종료에 스크립트를 다음 넣어 (이전 명령이 실패) exit 1그 내부 (또는 무엇이든) if애프터 블록 echo.

명령을 실행 중이고 다음을 사용하여 출력을 테스트하려는 경우 종종 더 간단합니다.

if some_command; then
    echo command returned true
else
    echo command returned some error
fi

또는 !부정을 위해 사용을 돌리기 위해

if ! some_command; then
    echo command returned some error
else
    echo command returned true
fi

그 중 어느 것도 오류 코드가 무엇인지 신경 쓰지 않습니다 . 특정 오류 코드에만 관심이있는 경우 $?수동으로 확인 해야합니다.


11
@ deadcell4 프로그램 실패시 쉘 스크립트를 종료해야 할 때 다음 관용구가 유용하다a_command || return 1
— gboffi

10
@gboffi return는 함수와 소스 스크립트에서만 작동합니다. 당신은 필요 exit(함수에 너무 많이 수행하고 소스 스크립트하는) 다른 경우에. 그러나 특정 정리 또는 추가 출력이 필요하지 않은 경우 확실히 합리적인 패턴입니다.
— Etan Reisner 2013 년

1
dash많은 현대 리눅스 배포판의 기본 비 대화식 쉘 은 실행 된 쉘 스크립트 return와 exit내부의 구별을 신경 쓰지 않는다고 말해야합니다 . dash내가 사용하더라도 스크립트를 종료합니다 return.
— gboffi

마지막 두 검사의 논리는 무엇입니까? if <command>종료 코드가 0이면 조건 이 통과 되는 것은 반 직관적 인 것처럼 보입니다. 다른 언어에서는 다른 방법 일 것입니다.
— sjw

3
중요 참고 : 파이프에는 작동하지 않습니다. if ! some_command | some_other_commandsome_command의 상태를 무시합니다. 대부분의 명령 해결 방법은 set -o pipefail(프로그램의 다른 부분에서 기능이 변경 될 수 있음) 또는 if명령문을 if [[ ${PIPESTATUS[0]} -ne 0 ]]별도의 후속 명령 (추악하지만 기능적) 으로 옮기는 것 입니다. 당신이 사용하는 경우 set -e다음 당신은 또한 추가 할 수 있습니다 || true제공하는 제어 흐름에서 파이프를 제거하기 때문에 두 번째 솔루션을 사용할 때 파이프의 끝에 if것, 그렇지 않으면 즉시 종료 원인.
— Alex Jansen

186

종료 코드! = 0은 오류를보고하는 데 사용됩니다. 따라서 수행하는 것이 좋습니다.

retVal=$?
if [ $retVal -ne 0 ]; then
    echo "Error"
fi
exit $retVal

대신에

# will fail for error codes > 1
retVal=$?
if [ $retVal -eq 1 ]; then
    echo "Error"
fi
exit $retVal

retVal에서 테스트해야합니다. $? retVal을 지정한 후에는 명령의 반환 값이 아닙니다.
— anr78

실제로는 아닙니다 : mywiki.wooledge.org/BashFAQ/002- 그러나 편집이 가독성을 향상 시킨다는 데 동의합니다.
— Oo.oO

1
방금이 게시물을 발견했습니다 stackoverflow.com/questions/20157938/…
— anr78

dnf check-update0 (업데이트 없음), 100 (사용 가능한 업데이트) 또는 1 (오류)을 반환합니다.
— jww

1
@jww-글쎄, 그것은 컨벤션에 반대하는 것은 좋지 않습니다 ( gnu.org/software/bash/manual/html_node/Exit-Status.html ). 그러나이를 막을 수있는 것은 없습니다. dnf개발자가이 방법을 선택 했다면 , 그들이 선택한 것입니다. 그러나 여전히 그들의 선택은 사양을 깨뜨리지 않습니다 :)
— Oo.oO

44

$?다른 매개 변수와 같습니다. 최종적으로 호출하기 전에 사용할 값을 저장할 수 있습니다 exit.

exit_status=$?
if [ $exit_status -eq 1 ]; then
    echo "blah blah blah"
fi
exit $exit_status

29

명시 적 if진술의 대안

최소한 :

test $? -eq 0 || echo "something bad happened"

완전한:

EXITCODE=$?
test $EXITCODE -eq 0 && echo "something good happened" || echo "something bad happened"; 
exit $EXITCODE

13

도움이되고 자세한 답변 을 추가하려면 다음을 수행하십시오 .

종료 코드를 명시 적으로 확인해야하는 경우 다음과 같이 산술 연산자를 사용하는 것이 좋습니다 (( ... )).

run_some_command
(($? != 0)) && { printf '%s\n' "Command exited with non-zero"; exit 1; }

또는 case진술을 사용하십시오 .

run_some_command; ec=$?  # grab the exit code into a variable so that it can
                         # be reused later, without the fear of being overwritten
case $ec in
    0) ;;
    1) printf '%s\n' "Command exited with non-zero"; exit 1;;
    *) do_something_else;;
esac

Bash의 오류 처리에 대한 관련 답변 :

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.