Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"set -e" does not cause a code block to exit if in a conditional

Tags:

bash

I'm trying to figure out why the bail-on-error behavior -e does not kick in if the failing block is in a conditional chain:

#!/bin/bash
set -e
{       echo "First"
        ls blat
        echo "(this should not print)"
}

Prints out:

First
ls: cannot access 'blat': No such file or directory

which is correct.

Whereas the following:

#!/bin/bash
set -e
{       echo "First"
        ls blat
        echo "(this should not print)"
} || echo "Encountered an error"

Prints out:

First
ls: cannot access 'blat': No such file or directory
(this should not print)

I expect Encountered an error to be printed instead of this should not print

Can anybody explain to me the reason for the discrepancy?

like image 729
tk-noodle Avatar asked Sep 15 '25 01:09

tk-noodle


1 Answers

From the documentation (emphasis mine):

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 !.

Because ls is part of the {...} compound executed as a non-final part of the || list, the script does not exit when ls has a non-zero exit status.

like image 56
chepner Avatar answered Sep 16 '25 14:09

chepner