Der ERR
Trap soll keinen Code ausführen, wenn die Shell selbst mit einem Fehlercode ungleich Null beendet wird, sondern wenn ein Befehl, der von dieser Shell ausgeführt wird, die nicht Teil einer Bedingung ist (wie in if cmd...
oder cmd || ...
...), mit einem Fehlercode ungleich Null beendet wird Beendigungsstatus (die gleichen Bedingungen set -e
, unter denen die Shell beendet wird).
Wenn Sie Code beim Beenden der Shell mit einem Exit-Status ungleich Null ausführen möchten, sollten Sie EXIT
stattdessen einen Trap hinzufügen und $?
dort Folgendes überprüfen :
trap '[ "$?" -eq 0 ] || echo hi' EXIT
Beachten Sie jedoch, dass bei einem überfüllten Signal sowohl die Signal-Trap als auch die EXIT-Trap ausgeführt werden.
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
Oder um den Ausgangsstatus wie $((signum + 128))
bei Signalen zu verwenden:
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
Beachten Sie jedoch, dass das normale Beenden bei SIGINT oder SIGQUIT möglicherweise ärgerliche Nebenwirkungen hat, wenn Ihr übergeordneter Prozess eine Shell wie diese ist bash
, die das Warten und die kooperative Beenden- Behandlung von Terminal-Interrupts implementiert . Vielleicht möchten Sie sich also mit demselben Signal umbringen, um Ihren Eltern mitzuteilen, dass Sie tatsächlich unterbrochen wurden, und dass sie in Betracht ziehen sollten, sich selbst zu beenden, wenn sie ein SIGINT / SIGQUIT erhalten haben.
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
Wenn die ERR
Falle ausgelöst werden soll, führen Sie einfach einen Befehl mit einem Exit-Status ungleich Null wie false
oder aus test
.