I was wondering whether set -e
propagates through subshells (i.e. does a subshell inherit the -e
setting of its parent), so I made some experiments. I found some strange results that I can't explain.
First, here are some basic tests. They return what I expect.
( true; false ) # 1
( false; true ) # 0
( set -e; false; true ) # 1
Now I tried what happens if I put a subshell within my subshell. This expression returns 1, which suggests that it propagates.
( set -e; ( false; true ) )
Then I tried these expressions. I expected them to return 1, but I found that they return 0.
( set -e; ( true; false ); true )
( set -e; ( set -e; false; true ); true )
Why? In both cases, the inner subshell returns 1, whether set -e
propagates or not (as I checked in the beginning). The outer subshell has set -e
, which means that it should fail after the inner subshell exits, but it does not. Can someone explain this?
Prior to bash
4, set -e
appears to only cause the shell to exit if a simple command has a non-zero exit (emphasis mine):
-e Exit immediately if a simple command (see SHELL GRAMMAR above) exits with a non-zero status.
In bash
4 (possibly 4.1, I don't have a 4.0 to check), the effect of -e
was extended to more complicated commands:
-e Exit immediately if a pipeline (which may consist of a single simple command), a subshell com- mand enclosed in parentheses, or one of the commands executed as part of a command list enclosed by braces (see SHELL GRAMMAR above) exits with a non-zero status.