1

Let's say we have a script like this.

#!/bin/bash
set -e
ls notexist && ls notexist
echo still here

won't exit because of set -e

but

#!/bin/bash
set -e
ls notexist || ls notexist
echo still here

will. Why?

dspjm
  • 5,473
  • 6
  • 41
  • 62

2 Answers2

3

the bash manual says for set -e:

The shell does not exit if the command that fails is [...]
part of any command executed in a && or || list except the
command following the final && or ||

the dash manual says:

If not interactive, exit immediately if any untested command fails.
The exit status of a command is considered to be explicitly tested
if the command is used to control an if, elif, while, or until;
or if the command is the left hand operand of an “&&” or “||” operator.

for the AND test, the shell will stop early, during the test of the "left hand operand". because there are still tests, it will consider the entire command to be "tested" and thus will not abort.

for the OR test, the shell has to run all (both) tests, and once the last test fails, it will conclude that there has been an unchecked error and thus will abort.

i agree it's a bit counterintuitive.

umläute
  • 28,885
  • 9
  • 68
  • 122
1

Because as Bash manual says regarding 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 !.

The ls notexist || ls notexist command terminates the shell because the second (last) ls notexist exits unsuccessfully. The ls notexist && ls notexist doesn't terminate the shell, because execution of "&& list" is stopped after the first ls notexist fails and the second (last) one is never reached.

BTW, it's easier and more reliable to do such tests using true and false instead of specific commands such as ls notexist.

spbnick
  • 5,025
  • 1
  • 17
  • 22