The following bash script prints "This should never run!":
#!/bin/bash
set -e
func() {
echo "Bailing out..."
false # Should bail out because of set -e
echo "This should never run!"
}
func || true
What's going on here?
A simple conclusion to make is that set -e is not propagated inside functions. However, this is not the case. Changing the last line (func || true) to just func causes the function to stop at the false statement as expected.
Another hypothesis is that bash will start executing the function, and on the first error (false) evaluate the rest of the line it was called on (func || true), and if that retuns 0 (true), then it continues executing the function as if nothing happened. However, replacing true with echo "Oops!" disproves that, since no "Oops!" is printed.
Is set -e somehow ignored when executing functions as part of a boolean expression?
set -eis full of corner cases, and in many circles considered more trouble than it's worth; see mywiki.wooledge.org/BashFAQ/105, as well as fvue.nl/wiki/Bash:_Error_handling and wiki.bash-hackers.org/scripting/obsolete -- to quote from that latter: The set -e feature generates more questions and false bug reports on the Bash mailing list than all other features combined!check_something || do_somethingshouldn't exit ifcheck_somethingfails; if it did, that would meanset -eand branching operations would be incompatible with each other. Unfortunately, the specification was sufficiently ill-thought-out that what we ended up with is a case whereset -eis completely disabled if anywhere up the stack the result of an ongoing operation will be used for a branch... and since it's specified by POSIX and honored by compliant existing shells, that behavior can't be fixed without massive compatibility problems.set -eand branching operations were in fact incompatible with each other, so long as it were a per-stack-frame flag -- this would mean it would need to be explicitly turned on when folks are too lazy to write|| return(or|| exitwhen outside a function) and turned back off afterwards, but at least the behavior would be consistent and obvious, and easy to audit].