답변:
ERR
트랩은 쉘 자체가 아닌 에러 코드와 함께 종료 할 때 코드를 실행하지만,하지 때 모든 명령 A의 일부가 아닌 그 쉘이 실행 조건 (처럼 if cmd...
, 또는 cmd || ...
비 제로와 ...) 종료 종료 상태 ( set -e
쉘을 종료시키는 원인과 동일한 조건 ).
종료 상태가 0이 아닌 쉘 종료시 코드를 실행 EXIT
하려면 대신 트랩을 추가 하고 확인하십시오 $?
.
trap '[ "$?" -eq 0 ] || echo hi' EXIT
그러나 트랩 된 신호에서 신호 트랩과 EXIT 트랩이 모두 실행되므로 다음과 같이 수행 할 수 있습니다.
unset killed_by
trap 'killed_by=INT;exit' INT
trap 'killed_by=TERM;exit' TERM
trap '
ret=$?
if [ -n "$killed_by" ]; then
echo >&2 "Ouch! Killed by $killed_by"
exit 1
elif [ "$ret" -ne 0 ]; then
echo >&2 "Died with error code $ret"
fi' EXIT
또는 $((signum + 128))
신호 와 같이 종료 상태를 사용하려면
for sig in INT TERM HUP; do
trap "exit $((128 + $(kill -l "$sig")))" "$sig"
done
trap '
ret=$?
[ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"' EXIT
그러나 SIGINT 또는 SIGQUIT에서 정상적으로 종료하면 상위 프로세스가 터미널 인터럽트 bash
의 대기 및 협업 종료 처리 를 구현 하는 쉘과 같은 경우에는 성가신 부작용이 발생할 수 있습니다 . 따라서 부모에게 실제로 중단되었으며 SIGINT / SIGQUIT를 받았을 때 자신을 종료해야한다고보고하기 위해 대신 동일한 신호로 자신을 죽이는 것이 좋습니다.
unset killed_by
for sig in INT QUIT TERM HUP; do
trap "exit $((128 + $(kill -l "$sig"))); killed_by=$sig" "$sig"
done
trap '
ret=$?
[ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"
if [ -n "$killed_by" ]; then
trap - "$killed_by" # reset handler
# ulimit -c 0 # possibly disable core dumps
kill -s "$killed_by" "$$"
else
exec "$ret"
fi' EXIT
당신이 원하는 경우 ERR
화재 트랩을 그냥 0이 아닌 종료와 같은 상태로 명령을 실행 false
또는 test
.
종료하지 않고 return을 사용하여 함수 종료시 상태를 설정하십시오 (반환없이 함수가 실패하면 상태는 마지막으로 실행 된 명령문의 상태입니다). 질문의 예에서 대체 return
하는 경우 다음 exit
과 같이 작동합니다. 나는 당신이 의도했다고 생각합니다 : 트랩은 ERR 의사 신호에서 트리거되고 'hi'가 인쇄됩니다. 추가 고려 사항을 보려면 다음을 시도하십시오.
#!/bin/bash
func()
{
echo 'in func'
return 99
echo 'still in func'
}
trap 'echo "done"' EXIT
trap 'status=$?; echo "error status is $status"; trap - EXIT; exit $status' ERR
func
echo 'returned from func'
0 리턴, ERR 트랩 주석 처리, ERR 핸들러 내 EXIT 트랩 취소, ERR 핸들러 종료 또는 리턴 제거 및 false
func의 마지막 명령문으로 설정 과 같은 다양한 수정을 시도 할 수 있습니다 .