우분투 12.04.2를 사용하고 있습니다. 쉘 스크립트에서 예외나 오류를 포착하기 위해 "trap" 명령을 사용하려고 하지만 수동으로 "error" 종료를 트리거하려고 합니다.
Exit1을 시도했지만 "오류" 신호가 발생하지 않습니다.
#!/bin/bash
func()
{
exit 1
}
trap "echo hi" INT TERM ERR
func
"오류" 종료 신호를 수동으로 트리거하는 방법을 모르시나요?
답변1
함정 ERR
은 셸 자체가 0이 아닌 오류 코드로 종료될 때 코드를 실행하는 것이 아니라, 셸이 0이 아닌 명령을 실행할 때 코드를 실행하는 것입니다.상황( if cmd...
또는 cmd || ...
...에서와 같이) 0이 아닌 종료 상태로 종료합니다( 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
하지만 상위 프로세스가 다음 과 같은 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
답변2
함수가 종료될 때 상태를 설정하려면exit 대신 return을 사용하십시오(함수가 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'
false
0 반환, ERR 트랩 주석 처리, ERR 핸들러에서 EXIT 트랩 취소 안 함, ERR 핸들러에서 종료 안 함, return 제거 및 func의 마지막 문으로 만드는 등 다양한 수정을 시도할 수 있습니다.