-
-
Save eentzel/3937aa88f8e263ace3d2 to your computer and use it in GitHub Desktop.
| $ cat test.sh | |
| #!/usr/bin/env bash | |
| set -e | |
| foo () { | |
| echo $(echo "subshell foo"; exit 11) | |
| } | |
| bar () { | |
| result=$(echo "subshell bar"; exit 22) | |
| echo $result | |
| } | |
| indirection () { | |
| var=$(bar) | |
| echo "indirect", $var | |
| } | |
| foo | |
| indirection | |
| bar | |
| $ ./test.sh | |
| subshell foo | |
| indirect, subshell bar | |
| $ echo $? | |
| 22 | |
| $ |
The issue seems to be with command substitutions specifically, and variable assignments having odd semantics around them.
-e Exit immediately if a command exits with a non-zero status.
$(...) is a command substitution, not a command. The actual command in foo is echo $(...), which exist with status 0. bar's command is a variable set without a command name:
If there is a command name left after expansion, execution proceeds as described below. Otherwise, the command exits. If one of the expansions contained a command substitution, the exit status of the command is the exit status of the last command substitution performed. If there were no command substitutions, the command exits with a status of zero.
It also looks like -e doesn't correctly propagate in bash, but does in dash. dash otherwise has the same semantics regarding the substitution.
$ bash
bash$ (set -e; echo $(echo foo; false; echo bar)))
foo bar
bash$ exit
$ sh
dash$ (set -e; echo $(echo foo; false; echo bar)))
fooWell, at least this explains a lot of the similar issues I had in the past.
Also looks like github's having issues updating comments, the one with the link didn't show for me until I added my (now rather redundant) comment...
Today I Learned that
set -edoesn't apply to a to a subshell unless you assign the result to a variable...