Bash script with `set -e` doesn't stop on `... && ...` command
This is documented behavior.
The bash(1) man page says, for set -e
,
The shell does not exit if the command that fails is part of the command list immediately following a
while
oruntil
keyword, part of the test following theif
orelif
reserved words, part of any command executed in a&&
or||
list except the command following the final&&
or||
, any command in a pipeline but the last, or if the command's return value is being inverted with!
.
[Emphasis added.]
And the POSIX Shell Command Language Specification confirms that this is the correct behavior:
The
-e
setting shall be ignored when executing the compound list following thewhile
,until
,if
, orelif
reserved word, a pipeline beginning with the!
reserved word, or any command of an AND-OR list other than the last.
and Section 2.9.3 Lists of that document defines
An AND-OR list is a sequence of one or more pipelines separated by the operators "
&&
" and "||
" .
The set -e
option doesn't have effect in some situations, and this is the standard behavior and portable across POSIX compliant shell.
The failed command is part of pipeline:
false | true; echo printed
will print printed
.
And only the failure of the pipeline itself is considered:
true | false; echo 'not printed'
will print nothing.
The failed command run in the compound list following the while
, until
, if
, elif
reserved word, a pipeline beginning with the !
reserved word, or any command as part of &&
or ||
list except the last one:
false || true; echo printed
The last command fails still make set -e
affected:
true && false; echo 'not printed'
The subshell fails in a compound command:
(false; echo 'not printed') | cat -; echo printed
my guess is if-then condition as a whole evaluate to true.
I tried
set -e
if cd not_existing_dir
then echo 123
fi
echo "I'm running! =P"
who give
-bash: cd: not_existing_dir: No such file or directory
I'm running! =P
error code is catch by if condition, thus bash will not trigger end of execution.