
내 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: set -e(또는 set -o errexit 또는 트랩 ERR)가 예상한 대로 작동하지 않는 이유는 무엇입니까?