According to this thread, it's the behavior POSIX specifies for using "
set -e" in a subshell.
(I was surprised as well.)
First, the behavior:
-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.
The second post notes,
In summary, shouldn't set -e in (subshell code) operate independently
of the surrounding context?
No. The POSIX description is clear that surrounding context affects
whether set -e is ignored in a subshell.
There's a little more in the fourth post, also by Eric Blake,
Point 3 is not requiring subshells to override the contexts where
-e is ignored. That is, once you are in a context where
-e is ignored,
there is nothing you can do to get
-e obeyed again, not even a subshell.
$ bash -c 'set -e; if (set -e; false; echo hi); then :; fi; echo $?'
Even though we called
set -e twice (both in the parent and in the
subshell), the fact that the subshell exists in a context where
ignored (the condition of an if statement), there is nothing we can do
in the subshell to re-enable
This behavior is definitely surprising. It is counter-intuitive: one would expect the re-enabling of
set -e to have an effect, and that the surrounding context would not take precedent; further, the wording of the POSIX standard does not make this particularly clear. If you read it in the context where the command is failing, the rule does not apply: it only applies in the surrounding context, however, it applies to it completely.