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많은 현대 리눅스 배포판의 기본 비 대화식 쉘 은 실행 된 쉘 스크립트 returnexit내부의 구별을 신경 쓰지 않는다고 말해야합니다 . 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.