I thought 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
Prints
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)?
Edit:
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 ||
with ;
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
OUTPUT:
FORK'D:
dash 0
bash 0
ksh 0
zsh 0
EXEC'D:
dash 1
bash 1
ksh 1
zsh 1
-e
documentation part of set. – cuonglm Jul 18 '16 at 02:28