Here's a simple script that sets up a temp dir in the current dir and a trap to delete it on exit.
#filename: script
set -x
trap 'rm -rf "$d"' exit
d=`TMPDIR=$PWD mktemp -d`
"$@"
If I do ksh script sleep 100
or bash script sleep 100
and interrupt it with, C-C
, the trap gets executed and the directory is deleted.
It doesn't work with dash
. Why? Is this a bug or intended behavior?
Best Answer
zsh
,pdksh
(though not recent versions ofmksh
derived from that),yash
, the Bourne shell behave likedash
.Only
bash
,ksh88
,ksh93
andmksh
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 whenexit
is invoked, but AFAICT, it doesn't even say for instance if it should be evaluated when the shell exits as the result ofset -e
orset -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
andbash
do, but the list of signals they handle is different between all three implementations. The only signals common between all 3 seem to beINT
,QUIT
,TERM
,ALRM
andHUP
.If you want the
EXIT
trap to be run upon some signals, the portable way would be to handle those signals yourself:That approach however doesn't work with
zsh
, which doesn't runEXIT
trap ifexit
is called from a trap handler.It also fails to report your death-by-signal to your parent.
So instead, you could do:
Now, beware though that if more signals arrive while you're executing
cleanup
,cleanup
may be run again. You may want to make sure yourcleanup
works correctly if invoked several times and/or ignore signals during its execution.