Consider the following:
#!/bin/bash
trap 'echo $?' INT
kill -INT $$
Output: 0
Here I would expect 130
for my system. Of course, if I do a Ctrl + C
then I get 130
.
The same thing happens for any other signal like HUP
or TERM
. I found this behavior surprising because if you have a trap
set up to capture many signals then there's no way to exit with the correct error code for what signal called your handler:
#!/bin/dash
exit_abrupt() {
exit_code=$?
echo "Encountered an error, cleaning up..." >&2
# *clean up*
exit "$exit_code" # This will return 0!
}
trap exit_abrupt HUP INT TERM
kill -HUP $$
I've tested Bash, Dash, and ZSH, all of which exhibit this behavior. Is this how it's supposed to work across shells? Is it documented by POSIX (can someone point to the documentation)? How else can I know the correct exit code that works across shells?
The best POSIX documentation I've found reads:
The value of "$?" after the trap action completes shall be the value it had before trap was invoked.
which to me sounds like it should be passing though the signal in all cases and yet it's not so I must be missing something...