Is it possible to propagate an exit code to the caller in case of a syntax error in a Bash script with an EXIT trap? For example, if I have:
#! /bin/bash
set -eu
trap "echo dying!!" EXIT
echo yeah
echo $UNBOUND_VARIABLE
echo boo
Then, running it gives an exit code 0 even if the script did not really end successfully:
$ bash test.sh
yeah
test.sh: line 8: UNBOUND_VARIABLE: unbound variable
dying!!
$ echo $?
0
But if I comment out the exit trap, the script returns 1. Alternatively, if I replace the line with the unbound variable with a command that returns nonzero (e.g. /bin/false
), that exit value is propagated as I would like it to.
To end a shell script and set its exit status, use the exit command. Give exit the exit status that your script should have. If it has no explicit status, it will exit with the status of the last command run.
Any commands above the trap can exit and not be caught in the trap. Now if the script exits for any reason, it will still run the rm command to delete the file. Here is an example of me sending SIGINT (CTRL+C) to interrupt the script while it is running.
The shell exits with the result of the last executed command. In your trap case, that's echo
, which usually returns with success.
To propagate your value, simply exit
with it.
#!/bin/bash
set -eu
die() {
echo "Dying!!"
exit "$1"
}
trap 'die $?' EXIT
echo yeah
echo $unbound
echo boo
Also note that set -e
is considered harmful -- it makes you think the script will exit if a command fails, which it won't always do.
This behavior is related to different Bash versions. The original script works as expected on Bash 4.2 but not on 3.2. Having the error-prone code in a separate script file and running it in a subshell works around problems in earlier Bash versions:
#!/bin/bash
$BASH sub.sh
RETVAL=$?
if [[ "$RETVAL" != "0" ]]; then
echo "Dying!! Exit code: $RETVAL"
fi
sub.sh:
set -eu
echo yeah
echo $UNBOUND_VARIABLE
echo boo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With