This specific behavior is still found in "GNU bash, Version
4.4.12(1)-release" from Debian 9 Stretch, but a new shell option
enables the more consistent behavior of other shells.

Subshells for command substitutions do not automatically inherit
the option "errexit". This must be enabled by another option
"inherit_errexit". The manual page for the bash explains it like:

inherit_errexit
        If  set,  command substitution inherits the value of the
        errexit option, instead of unsetting it in the  subshell
        environment.   This option is enabled when posix mode is
        enabled.

Using this option gives the expected result:

hb1@debian:~$ bash -c 'set -e ; z=$(false;echo foo) ; echo $z'
foo
hb1@debian:~$ echo $?
0
hb1@debian:~$ bash -c 'set -e ; shopt -s inherit_errexit ; z=$(false;echo foo) 
; echo $z'
hb1@debian:~$ echo $?
1

As mentioned in the manual, the POSIX mode also gives the expected
result:

hb1@debian:~$ bash --posix -c 'set -e ; z=$(false;echo foo) ; echo $z'
hb1@debian:~$ echo $?
1

The Bash Reference Manual explains the difference:

42. Enabling POSIX mode has the effect of setting the inherit_errexit
    option, so subshells spawned to execute command substitutions
    inherit the value of the -e option from the parent shell. When
    the inherit_errexit option is not enabled, Bash clears the -e
    option in such subshells.

The Bash Reference Manual can be installed with the Debian package
"bash-doc". Then see:

file:///usr/share/doc/bash/bashref.html#Bash-POSIX-Mode


The option inherit_errexit is new in bash-4.4. The file
/usr/share/doc/bash/NEWS.gz lists it under the first topic:

This is a terse description of the new features added to bash-4.4
since the release of bash-4.3. [...]

ii. inherit_errexit: a new `shopt' option that, when set, causes
    command substitutions to inherit the -e option.  By default,
    those subshells disable -e.  It's enabled as part of turning on
    posix mode.

--
Regards,
Hartmut Buhrmester

Reply via email to