set -e had the same effect on subshells as on top-level shell.
Apparently, it does not. This:
( set -e false true ) || echo false1 bash -ec ' set -e false true ' || echo false2 bash <<EOF || echo false3 set -e false true EOF bash <<EOF || echo false4 false true EOF bash <<EOF || echo false5 false && true EOF
false2 false3 false5
Where is this documented? Can I get subshells to terminate on errors, without connecting all their commands with
&& (or without doing
|| exit $? after each command)?
My particular use case was something like:
set -e # ... status=0 ( false; true ) || status=$? report_code $status return $status
Where the contents of the subshell was my actual code.
The problem with this is it always sets status to 0 and replacing
; causes an unwanted error exit because of the outer set -e.
I solved it with:
set -e # ... set +e ( false; true ); status=$? set -e report_code $status return $status
I wish I didn't have to do this, but it appears all common shells show this execed-subshell vs just-forked-subshell dichotomy:
#!/bin/sh echo FORK\'D: export SH for SH in dash bash ksh zsh; do $SH -c 'st=0; ( set -e; false; true ) || st=$?; printf "%s\t%s\n" $SH $st; ' done echo EXEC\'D: for SH in dash bash ksh zsh; do $SH -c 'st=0; '$SH' -c " set -e; false; true " || st=$?; printf "%s\t%s\n" $SH $st; ' done
FORK'D: dash 0 bash 0 ksh 0 zsh 0 EXEC'D: dash 1 bash 1 ksh 1 zsh 1