Bash
如何使用 Trap 命令觸發錯誤
我正在使用 Ubuntu 12.04.2。我正在嘗試使用“trap”命令在我的 shell 腳本中擷取異常或錯誤,但我也在嘗試手動觸發“錯誤”退出。
我試過退出 1,但它不會觸發“錯誤”信號。
#!/bin/bash func() { exit 1 } trap "echo hi" INT TERM ERR func
不確定如何手動觸發“錯誤”退出信號?
陷阱不是在
ERR
shell 本身以非零錯誤程式碼退出時執行程式碼,而是當該 shell 執行的任何不屬於條件的命令(如 inif cmd...
或cmd || ...
…)以非零退出時退出狀態(與導致set -e
退出 shell的條件相同)。如果你想在 shell 退出時以非零退出狀態執行程式碼,你應該添加一個陷阱
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
但是請注意,當您的父程序是一個類似實現終端中斷的等待和協作退出處理的shell 時,在 SIGINT 或 SIGQUIT 上正常退出具有潛在的煩人副作用。因此,您可能希望確保使用相同的信號殺死自己,以便向您的父母報告您確實被打斷了,並且如果它收到 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
觸發陷阱,只需執行具有非零退出狀態的命令,例如false
ortest
。