2014-12-22 1 views
2

강력한 bash 스크립트를 작성하고 무언가가 잘못 될 때마다 스크립트가 실행되지 않도록하기 위해 set -e을 사용합니다. 그것은 훌륭하지만 여전히 구멍이 하나 있습니다 : 조건. if f; then .... fi을 작성하고 f 함수가 일부 명령 실행에 실패하면 스크립트가 종료되지 않습니다. 따라서 f에있는 모든 명령의 리턴 코드와 모든 서브 루틴 f invoke를 반복적으로 확인해야합니다. 이것은 성가신 일입니다.bash는 에러 상태로 에러를 처리합니다.

예 : bash의 일부 플래그 또는 옵션으로 조건 내에서도 실패합니다. 유일한 예외는 return 진술 내용 바로 안에 f입니다. fg이고 g이 1이면 오류로 간주됩니다. 단, g을 조건이라고도하는 경우 (if g; then ... fi) return 진술 내용이 g 인 경우 허용됩니다. 그래서 등등. 간결

+2

BashFAQ # 105 - http://mywiki.wooledge.org/BashFAQ/105 - 여기에 관련성이 있습니다. 답은 "아니요, 할 수는 없으므로"(false 및 설명 오류를 반환하는 데 사용되는 반환 상태가 하나이기 때문에) 질문에 완전히 대답하지는 않지만 ' set -e' 및 ERR 트랩 동작에 대해 자세히 설명합니다. –

답변

4

, 제

당신이 쉘, 실패에 종료 f을 테스트하지 않는합니다; 단순히 그것을 실행하십시오. then 절의 코드는 f이 성공한 경우에만 실행할 수 있기 때문에 f의 호출을 따라야합니다.

오래된 코드 :

set -e 
if f; then echo "f succeeded"; fi 

새로운 코드 :

set -e 
f 
echo "f succeeded" 
당신은 단지 그것을 성공 않을 경우 "F 성공"볼

; 실패하면 set -e 스크립트가 종료됩니다.

1

당신이하고 싶은 것은 약간 이상합니다. 난 당신이 요구하는지 이유를 두 가지 가능성 상상할 수 :

  1. 당신은 어떤 함수 f의 체내 잘못되면 스크립트가 종료하려면를 은 함수 자체는 여전히 성공을 반환 경우에도 마찬가지입니다.

  2. 합법적 인 거짓 값으로 판명 된 기능을 성공적으로 계산하고 실패하는 기능을 구분하고 싶습니다.

경우 1에 대해 - 그렇게하지 마십시오. f 내부에 문제가 발생하면 함수는 절대 false를 반환해야합니다 (전체 스크립트 자체를 종료하지 않은 경우). 그리고 그것이 거짓을 반환한다면, 당신은 훌륭합니다. @ JonathanLeffler의 대답을보십시오.

사례 2의 경우 효과적으로 $?이 두 가지 임무를 수행하도록하려고합니다. 오류 표시기이거나 부울 결과 일 수 있습니다. 둘 다 될 수는 없습니다.

무언가가 잘못되어 스크립트를 종료하려면 해당 기능을 호출 할 때 exit 함수를 호출하면됩니다. 따라서 호출자는이 경우에 대해 걱정할 필요가 없습니다.

또는 계산 된 부울 값을 반환하는 대신 echo 함수를 사용하고 성공/실패를 위해 $?을 예약 할 수 있습니다.아마 이런 식으로 뭔가가 :

f() { 
    if that thing is true; then 
    echo 1 
    else 
    echo 0 
    fi 
    if something went wrong; then 
    return 1 
    else 
    return 0 
    fi 
} 
result=$(f) # we'll blow up and exit if f returns nonzero in `$?` 
if ((result)); then 
    ... 
fi 
+0

나는 오류와 오류를 구별하기 위해'echo'와'return'을 사용하는 것을 좋아합니다. 아마도 그것을 코드에서 해결 방법으로 사용할 것입니다. 다른 한편으로, 나는 나의 요점을 좀 더 분명하게하고 싶다. 내 요점은, 강력한 쉘 스크립트를 작성하려는 경우 잠재적으로 잘못 될 수있는 모든 명령의 리턴 코드를 확인해야한다는 것이다. 그런 다음 논리는 어떤 명령이 조건에 의해 랩핑되지 않은 경우입니다. 'if '또는'&&'등, 그렇다면 결코 0이 아닌 값을 반환하지 않을 것이라고 기대합니다. 그렇다면 예상치 못한 일이며 스크립트가 종료되어야합니다. 그것은 의미가 있습니까? –

1

당신은 f 오류가 발생 거짓f 인을 구별해야합니다.

전통적으로 허위 및 오류 조건은 모두 같은 방식으로 신호가 보내집니다. $?을 0이 아닌 값으로 설정합니다.

일부 명령은 이러한 구분을합니다. 예를 들어 grep 명령은 패턴이 발견되면 $?0으로 설정하고 그렇지 않은 경우 1을 설정하고 오류가있는 경우 2을 설정합니다 (예 : 누락 된 파일). grep 명령에 대한 그래서, 당신은 같은 것을 할 수있는 :

grep ... 
case $? in 
    0) # ok 
     ;; 
    1) # pattern not found 
     ;; 
    *) # error 
     ;; 
esac 

을하지만 그 grep에 해당합니다. "거짓"결과를 내고 실패하는 명령을 구별하는 데는 보편적 인 규칙이 없으며 많은 경우 그러한 구별이 없습니다.

원하는 것을 수행하려면 오류를 구성하는 요소를 정의한 다음 각 명령에 대해 오류 상태를 감지하는 방법을 결정해야합니다.