set -e
is a bit subtle.
From the reference:
-e
When this option is on, when any command fails (for any of the reasons listed in Consequences of Shell Errors or by returning an exit
status greater than zero), the shell immediately shall exit, as if by
executing the exit special built-in utility with no arguments, with
the following exceptions:
- The failure of any individual command in a multi-command pipeline shall not cause the shell to exit. Only the failure of the
pipeline itself shall be considered.
The -e setting shall be ignored when executing the compound list following the while, until, if, or elif reserved word, a pipeline
beginning with the ! reserved word, or any command of an AND-OR list
other than the last.
If the exit status of a compound command other than a subshell command was the result of a failure while -e was being ignored, then
-e shall not apply to this command.
This requirement applies to the shell environment and each subshell environment separately. For example, in:
set -e; (false; echo one) | cat; echo two
the false command causes the subshell to exit without executing echo one; however, echo two is executed because the exit status of the
pipeline (false; echo one) | cat is zero.
Since false && true
is part of an AND or OR list and false
isn't the last, the shell doesn't exit immediately.
So echo success
is executed, and it's return code is 0
.
By the way, have you noticed case 6?