명령이 성공했는지 확인하는 방법?


234

명령 실행에 오류가 있는지 확인하는 방법이 있습니까?

예 :

test1=`sed -i "/:@/c connection.url=jdbc:oracle:thin:@$ip:1521:$dataBase" $search`
valid $test1

function valid () {
  if $test -eq 1; then
    echo "OK"
    else echo "ERROR" 
  fi
}

이미 시도했지만 작동하지 않는 것 같습니다. 나는 그렇게하지 않습니다.


9
중첩 할 수 있고 아포스트로피와 구별하기 쉽기 때문에 백 틱`foo` 보다 $ (foo) 를 선호하십시오 .
사용자 알 수 없음

1
BTW에서는 함수 valid를 호출하기 전에 함수 ( ) 를 정의해야 합니다.
wjandrea

답변:


344

반환 값은에 저장됩니다 $?. 0은 성공을 나타내고 다른 것은 오류를 나타냅니다.

some_command
if [ $? -eq 0 ]; then
    echo OK
else
    echo FAIL
fi

다른 텍스트 값과 마찬가지로 나중에 비교할 수 있도록 변수에 저장할 수 있습니다.

some_command
retval=$?
do_something $retval
if [ $retval -ne 0 ]; then
    echo "Return code was not zero but $retval"
fi

가능한 비교 연산자는을 참조하십시오 man test.


좋네요 ... 출력 오류를 잡을 수 있습니까 ?? !! ,이 경우에 나는 2 오류가 있기 때문에 : 명령 오류 "텍스트"ex, 파일을 찾을 수 없습니다 내 오류 "텍스트"예를 들어 실패했습니다
moata_u

@ moata_u : 내 대답에 표시된 것처럼 값을 변수에 저장할 수 있습니다.
Lekensteyn

@moata_u : ;앞에 elseand 를 넣어야합니다 fi:`if ...; 그런 다음 ...; 그렇지 않으면 ...; fi
Lekensteyn

4
이것은이다 쓸모 사용test .
David Foerster

1
@Blauhirn [ $? ](또는 동등하게 test $?)은 $?null이 아닌 숫자 (0, 1 등)로 평가 되므로 작동하지 않습니다 . 참고 항목 에 대한 문서를test "EXPRESSION를 생략하면, '테스트'false를 반환 EXPRESSION는 하나의 인수, '테스트'인수가 그렇지 않은 경우는 null과에 해당하는 경우 false를 반환 인 경우.."
Lekensteyn

87

명령의 성공 또는 실패 여부 만 알아야하는 경우에는 테스트를 귀찮게하지 말고 $?명령을 직접 테스트하십시오. 예 :

if some_command; then
    printf 'some_command succeeded\n'
else
    printf 'some_command failed\n'
fi

그리고 출력을 변수에 할당해도 반환 값은 변경되지 않습니다 (stdout이 터미널이 아닌 경우 다르게 동작하지 않는 한).

if output=$(some_command); then
    printf 'some_command succeded, the output was «%s»\n' "$output"
fi

http://mywiki.wooledge.org/BashGuide/TestsAndConditionals는 설명 if더 자세히.


실패 여부에 대한 부울을 .ini에 저장하는 것과 같이 분기 이외의 다른 작업을 수행하려면 어떻게해야합니까? 그런 다음 출력 변수는 그렇게하지 않지만 $?명령을 직접 테스트하는 것이 엄격하게 더 좋다고 말하는 것은 잘못되었습니다.
Timothy Swan

출력을 변수에 할당하면 local명령을 사용할 때 , 즉 출력을 local foo=$(false); echo $?;생성 할 때 반환 값이 변경 될 수 있습니다 0. 그러나 localbash 함수 내부에만 관련이 있습니다.
Cromax

26
command && echo OK || echo Failed

command화면에 오류가 반환 되면 숨기는 방법은 무엇입니까?
Sigur

경우 command표준 에러 밖으로 오류를 기록, 당신은 양식을 사용할 수 있습니다 command 2> /dev/null && echo OK || echo Failed. 2> /dev/null리디렉션 출력 표준 에러 /dev/null. 그러나 일부 유틸리티는 stdout에 오류를 기록합니다 (이 방법은 좋지 않습니다). 이 경우 리디렉션에서 2를 생략 할 수 있지만 명령의 출력이 손실됩니다. 성공을 확인하는이 방법은 간단한 삼항 논리에는 좋지만보다 복잡한 동작의 경우 $?명령 성공 을 확인 하거나 if@geirha의 답변에 요약 된 블록 방법을 사용하는 것이 가장 좋습니다 .
벤더 더 위대한

17

$? 이전 명령의 종료 상태를 포함해야하며 오류가 없으면 0이어야합니다.

그래서, 같은 것;

cd /nonexistant
if [ $? -ne 0 ]
then
    echo failed
else
    echo success!
fi

대부분의 경우 && 구문을 사용하여 서로 의존해야하는 명령을 연결하는 것이 더 쉽습니다. 그래서 cd /nonexistant && echo success!하지 &&하기 전에 명령 나누기 때문에 성공을 에코. 이것의 추론 || 인 cd /nonexistant || echo fail CD가 실패했기 때문에 실패 에코. (이것은 || exit과 같은 것을 사용하면 유용하게됩니다. 이전 명령이 실패하면 스크립트가 종료됩니다.)


좋네요 ... 출력 오류를 잡을 수 있습니까 ?? !! ,이 경우에 나는 2 오류가 있기 때문에 : 명령 오류 "텍스트"ex, 파일을 찾을 수 없습니다 내 오류 "텍스트"예를 들어 실패했습니다
moata_u


5
command && echo $? || echo $?

당신은 의미 command; echo $?합니까?
Javier Buzzi 10

아니요, 내 줄은 정확합니다. 실패 여부에 관계없이 실제 결과 코드를 숫자로 제공합니다.
modrobert

1
자, 이것들에 대한 차이점을 설명해주세요 : true && echo $? || echo $?/ true; echo $?and false && echo $? || echo $?/ false; echo $?-당신도 알
다시피

예, 동일한 결과이지만 조건이 없습니다. 원래 질문은 "명령이 성공했는지 확인하는 방법?"이었습니다. 이것은 이전 답변을 기반으로합니다. 더 좋은 예는 다음과 같습니다.command && echo "success: $?" || echo "fail: $?"
modrobert

5

접근의 유형 if...then...fi&&/ 또는 ||유형은 우리가 테스트하고자하는 명령에 의해 종료 된 종료 상태를 처리 한다는 점에 유의해야합니다 (성공시 0). 그러나 일부 명령은 명령이 실패했거나 입력을 처리 할 수없는 경우 0이 아닌 종료 상태를 리턴하지 않습니다. 이것은 일반적인 명령 if&&/ ||접근 방식이 특정 명령에 대해 작동하지 않음을 의미 합니다.

예를 들어, Linux file에서 존재하지 않는 파일을 인수로 받고 find지정된 파일 사용자를 찾을 수없는 경우 GNU는 여전히 0으로 종료 됩니다.

$ find . -name "not_existing_file"                                          
$ echo $?
0
$ file ./not_existing_file                                                  
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?
0

이러한 경우 상황을 처리 할 수있는 잠재적 인 방법 중 하나는 stderr/ stdin메시지 file와 같이 명령에 의해 반환 된 메시지를 읽거나와 같이 명령 출력을 구문 분석하는 것입니다 find. 이를 위해 case진술을 사용할 수 있습니다.

$ file ./doesntexist  | while IFS= read -r output; do                                                                                                                  
> case "$output" in 
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed

$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi                                                                                     
File not found

(이것은 unix.stackexchange.com 에서 관련 질문에 대한 내 자신의 답변을 다시 게시 한 것입니다 )


1

다른 많은 답변에서 언급했듯이 간단한 $?유언장 테스트 는 다음과 같습니다.

if [ $? -eq 0 ]; then something; fi

명령이 실패 했는지 테스트하려면 bash다음과 같이 더 짧은 버전을 사용할 수 있습니다 (하지만 과도 할 수 있음).

if (($?)); then something; fi

이것은 (( ))산술 모드 를 사용하여 작동 하므로 명령이 반환 된 success경우 즉 $? = 0, 테스트는 테스트를 ((0))어떤 테스트로 평가하면 false그렇지 않으면를 반환 true합니다.

성공 을 테스트하기 위해 다음을 사용할 수 있습니다.

if ! (($?)); then something; fi

그러나 이미 첫 번째 예보다 그리 짧지는 않습니다.


1
건설적인 비판?
afuna


-2

만약 [$ (command)]; 그런 다음 "성공"을 에코하십시오. fi


3
true성공 if [ $(true) ]; then echo "succeed"; fi했지만 succeed인쇄되지 않습니다. 실제로 이것은 command성공 여부를 확인하지 않습니다 . geirha의 게시물if command 과 같이 사용해야합니다 . 이다 명령 치환 . A는 조건식 . 결석 단어 분할 및 파일 이름 확장 하는 경우, 이것은 기본적으로 테스트 출력을했다. $( )[ ]command
엘리아 케이건
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.