This question already has an answer here:
Can't figure out a fitting title, I don't understand the behavior in dash/bash. Namely I am using set -e to bail out if a command fails, and command groups to handle the positive result.
ie. the general scheme is:
[ ! wantcommand ] || command
Than means the command only gets executed if needed, and a failure will automatically kill the script.
There might be some postprocessing necessary, in that case I use this:
[ ! wantcommand ] || { command && postprocess; }
This has led to some curious bughunting, as this wont kill the shell and I cant get behind the reason. I have to go through some chunks of shell code now, but would like to understand the reason.
for testing:
bash -c 'set -e; { false || false && echo "post" ; }; echo "ec $?"'
or:
bash -c 'set -e; { set -e; false || false && echo "post" ; }; echo "ec $?"'
Note: I am not asking for a fix, but primary why the returncode is 1, but the shell wont quit
set -e
only bails on unchecked failures.When you branch on a failure (using
if
,until
,while
,&&
or||
), that failure is checked.If the specification were not written in this manner, short-circuiting boolean operations could not effectively be used for flow control because the false branches would always cause an exit.
To quote from the specification, with emphasis added:
Note that this specification has changed over time; shells implementing a prior revision of the POSIX specification may not precisely comply with the version quoted here.
To inject some opinion here -- I'd strongly suggest reading BashFAQ #105 and ensuring that you fully understand all behaviors described therein before making the decision to use
set -e
rather than implementing explicit error-handling by hand. The FVUE wiki further describes the distinctions in behavior betweenset -e
in bash-native mode and POSIX mode, which should likewise be understood.