나는 Bash 스크립트에서 오류를 포착하고 발생한 내용을 로그에 출력하기 위해 ERR 트랩을 사용하고 있습니다. (이 질문과 유사:트랩, ERR 및 에코 오류 라인) 예상대로 작동합니다. 유일한 문제는 내 스크립트의 어느 시점에서 종료 코드 !=0이 발생할 것으로 예상된다는 것입니다. 이 상황에서 트랩이 작동하는 것을 어떻게 방지할 수 있습니까?
다음은 몇 가지 코드입니다.
err_report() {
echo "errexit on line $(caller)" | tee -a $LOGFILE 1>&2
}
trap err_report ERR
그런 다음 나중에 스크립트에서 다음을 수행합니다.
<some command which occasionally will return a non-zero exit code>
if [ $? -eq 0 ]; then
<handle stuff>
fi
명령이 0이 아닌 값을 반환할 때마다 내 트랩이 트리거됩니다. 이를 방지하기 위해 코드의 이 부분을 대상으로 삼을 수 있습니까?
이 질문을 확인했습니다."set -eu" 사용 시 EXIT 및 ERR 트랩의 올바른 동작 하지만 저는 이것을 제 경우에 어떻게 적용해야 할지 잘 모르겠습니다.
답변1
오류 코드를 즉시 "잡으면" ERR
trap
실행되지 않습니다.할 수 있는if
항상 오류 추적 기능을 켜거나 끄는 대신 명령문 등을 사용하십시오 . 그러나 당신은할 수 없다흐름 제어 검사를 사용 $?
하면 이미 (아마도) 잡히지 않은 오류가 있을 수 있습니다.
실패할 것으로 예상되는 명령이 있는 경우 -원하지 않는다이러한 실패 트리거를 원하려면 trap
간단히 실패를 포착하면 됩니다. 이를 명령문으로 묶는 것은 if
투박하고 장황하지만 다음 약어는 잘 작동합니다.
/bin/false || : # will not trigger an ERR trap
그러나 명령이 실패할 때 작업을 수행하려면 if
다음과 같이 하면 됩니다.
if ! /bin/false; then
echo "this was not caught by the trap!"
fi
또는 else
오류 상태도 캡처됩니다.
if /bin/false; then
: # dead code
else
echo "this was not caught by the trap!"
fi
요약하자면, 즉각적이고 본질적으로 설명되지 않는 오류 조건이 있는 경우에만 set -e
트립 이 발생합니다.trap "command" ERR
답변2
ERR
필요에 따라 코드 일부에서 트랩을 활성화/비활성화할 수 있습니다.
#!/bin/bash
err_report() {
echo "errexit on line $(caller)"
}
trap err_report ERR
trap - ERR # disable ERR trap
false
if [ $? -eq 0 ]; then
printf "OK\n"
else
printf "FAIL\n" # prints FAIL
fi
trap err_report ERR # enable ERR trap
false # prints errexit on line 14
답변3
나는 종종 ERR 트랩을 피하고 싶지만 함수의 반환 코드를 버리고 싶지도 않습니다. 그래서 제가 사용하는 패턴은 다음과 같습니다.
RC=0
some_function || RC=$?
그런 다음 RC를 사용하여 필요한 모든 작업을 수행합니다.
답변4
이 ERR
트랩은 와 동일한 규칙을 따릅니다 set -e
. 즉, 조건으로 사용되는 명령에는 적용되지 않습니다. 그래서,
trap "echo error" ERR
false # this should trigger the trap
if ! false; then # this shouldn't
echo handle stuff
fi
조건의 명령은 다음과 if
같을 수 있음 을 기억하십시오.어느반드시 그런 것은 아닌 명령입니다 [ .. ]
. 따라서 명령 종료 상태에 대한 true/false 평가를 원할 경우 if
조건에서 직접 사용하면 됩니다.
종료 코드를 저장해야 하는 경우그리고함정을 피하려면 ERR
다음과 같은 작업을 수행해야 합니다.
somecmd && :; ret=$?
여기서 트랩은 &&
압축되지만 ERR
종료 코드가 0일 때만 실행되므로 이후의 종료 코드가 동일하다는 것을 알 수 있습니다 :
.
확인하고 싶을 수도 있습니다BashFAQ 105: -e를 설정(또는 -o errexit 또는 트랩 ERR을 설정)해도 예상한 대로 작동하지 않는 이유는 무엇입니까?