bash script – Why ‘set -e’ Doesn’t Stop on ‘… && …’ Command

bashshellshell-script

I use set -e to stop bash script on first error.

All work OK unless I use command with &&:

$ cat script
set -e
cd not_existing_dir && echo 123
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
I'm running! =P
$

compared with:

$ cat script
set -e
cd not_existing_dir
echo "I'm running! =P"
$
$ ./script
./script: line 2: cd: not_existing_dir: No such file or directory
$

The first example still echoes I'm running!, but the second one doesn't. Why do they behave differently?

UPD. Similar question: https://stackoverflow.com/questions/6930295/set-e-and-short-tests

Best Answer

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 or until keyword, part of the test following the if or elif 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 the while, until,if, or elif 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 "||" .

Related Question