the ERR
trap is not to run code when the shell itself exits with a non-zero error code, but when any command run by that shell that is not part of a condition (like in if cmd...
, or cmd || ...
...) exits with a non-zero exit status (the same conditions as what causes set -e
to exit the shell).
If you want to run code upon exit of the shell with non-zero exit status, you should add a trap on EXIT
instead and check $?
there:
trap '[ "$?" -eq 0 ] || echo hi' EXIT
Note however that upon a trapped signal, both the signal trap and the EXIT trap would be run, so you may want to do it like:
trap killed_by=INT INT
trap killed_by=TERM 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
Or to use exit status like $((signum + 128))
upon signals:
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
If you want the ERR
trap to fire, just run a command with a non-zero exit status like false
or test
.