Bash

如何使用 Trap 命令觸發錯誤

  • April 27, 2016

我正在使用 Ubuntu 12.04.2。我正在嘗試使用“trap”命令在我的 shell 腳本中擷取異常或錯誤,但我也在嘗試手動觸發“錯誤”退出。

我試過退出 1,但它不會觸發“錯誤”信號。

#!/bin/bash

func()
{
   exit 1
}

trap "echo hi" INT TERM ERR
func

不確定如何手動觸發“錯誤”退出信號?

陷阱不是在ERRshell 本身以非零錯誤程式碼退出時執行程式碼,而是當該 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觸發陷阱,只需執行具有非零退出狀態的命令,例如 falseor test

引用自:https://unix.stackexchange.com/questions/79648