zsh
, pdksh
(though not recent versions of mksh
derived from that), yash
, the Bourne shell behave like dash
.
Only bash
, ksh88
, ksh93
and mksh
behave otherwise.
The POSIX spec is not clear on what should be the correct behaviour, but there's nothing in there that says that the shell is allowed to override the default handler for the SIGINT
(or other) signal.
It says EXIT
trap action should be evaluated when exit
is invoked, but AFAICT, it doesn't even say for instance if it should be evaluated when the shell exits as the result of set -e
or set -u
or error conditions like syntax errors or failing special builtins.
To be able to run EXIT
trap upon reception of a signal, the shell would need to install a handler on that signal.
That's what ksh
, mksh
and bash
do, but the list of signals they handle is different between all three implementations. The only signals common between all 3 seem to be INT
, QUIT
, TERM
, ALRM
and HUP
.
If you want the EXIT
trap to be run upon some signals, the portable way would be to handle those signals yourself:
trap 'exit 1' INT HUP QUIT TERM ALRM USR1
trap 'cleanup' EXIT
That approach however doesn't work with zsh
, which doesn't run EXIT
trap if exit
is called from a trap handler.
It also fails to report your death-by-signal to your parent.
So instead, you could do:
for sig in INT QUIT HUP TERM ALRM USR1; do
trap "
cleanup
trap - $sig EXIT
kill -s $sig "'"$$"' "$sig"
done
trap cleanup EXIT
Now, beware though that if more signals arrive while you're executing cleanup
, cleanup
may be run again. You may want to make sure your cleanup
works correctly if invoked several times and/or ignore signals during its execution.
zsh
only behave likedash
in non-interactive session, it does the same asbash
andksh
in interactive session. – cuonglm Nov 04 '15 at 13:26kill -s $sig "'"$$"' "$sig"
above) a best practice in general, or is it only applicable withSIGINT
(as seen at section 5 at SignalTrap ) – iruvar Nov 11 '18 at 03:41EXIT
intrap - $sig EXIT
line? It is the only point where your answer diverges from the wooledge bash guide – Harold Fischer Mar 29 '19 at 04:10cleanup
being run twice upon signal delivery for shells like mksh or ksh93. – Stéphane Chazelas Mar 29 '19 at 08:41cleanup
ignore signals during it's execution? Would this need to be implemented inside the trap that callscleanup
or withincleanup
itself? – Harold Fischer Nov 27 '19 at 05:21-e
is used. – jarno Jul 06 '20 at 10:25"$$"
be passed literally to thetrap
command so the code of the trap be something likecleanup; trap - INT EXIT; kill -s INT "$$"
– Stéphane Chazelas Oct 24 '20 at 10:41$$
does not change within the script, if I have understood correctly. – jarno Oct 24 '20 at 11:22cleanup; trap - INT EXIT; kill -s INT 1234
(where 1234 is the value of $$ at the timetrap
was invoked and as you say shouldn't change). While both are equally valid, the output oftrap
in the former case is better as it conveys the intention and can be reused in a context where $$ is different. – Stéphane Chazelas Oct 24 '20 at 11:26