Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does set -e; true && false && true not exit?

Tags:

bash

According to this accepted answer using the set -e builtin should suffice for a bash script to exit on the first error. Yet, the following script:

#!/usr/bin/env bash

set -e

echo "a"
echo "b"
echo "about to fail" && /bin/false && echo "foo"
echo "c"
echo "d"

prints:

$ ./foo.sh 
a
b
about to fail
c
d

removing the echo "foo" does stop the script; but why?

like image 369
Marcus Junius Brutus Avatar asked Sep 11 '14 18:09

Marcus Junius Brutus


2 Answers

To simplify EtanReisner's detailed answer, set -e only exits on an 'uncaught' error. In your case:

echo "about to fail" && /bin/false && echo "foo"

The failing code, /bin/false, is followed by && which tests its exit code. Since && tests the exit code, the assumption is that the programmer knew what he was doing and anticipated that this command might fail. Ergo, the script does not exit.

By contrast, consider:

echo "about to fail" && /bin/false

The program does not test or branch on the exit code of /bin/false. So, when /bin/false fails, set -e will cause the script to exit.

Alternative that exits when /bin/false fails

Consider:

set -e
echo "about to fail" && /bin/false ; echo "foo"

This version will exit if /bin/false fails. As in the case where && was used, the final statement echo "foo" would therefore only be executed if /bin/false were to succeed.

like image 121
John1024 Avatar answered Sep 21 '22 14:09

John1024


Because that answer is not sufficiently specific enough.

It should say (bolded text is my addition):

# Any subsequent simple commands which fail will cause the shell script to exit immediately

Since the man page reads thusly:

-e      Exit  immediately if a simple command (see SHELL GRAMMAR
        above) exits with a non-zero status.  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 in an if statement, part of a && or ││
        list, or if the command’s return value is being inverted
        via  !.   A  trap on ERR, if set, is executed before the
        shell exits.

And SHELL GRAMMAR expands thusly:

SHELL GRAMMAR
   Simple Commands
       A simple command is a sequence of optional  variable  assignments  fol-
       lowed  by  blank-separated  words and redirections, and terminated by a
       control operator.  The first word specifies the command to be executed,
       and  is  passed  as  argument  zero.  The remaining words are passed as
       arguments to the invoked command.

       The return value of a simple command is its exit status,  or  128+n  if
       the command is terminated by signal n.
like image 43
Etan Reisner Avatar answered Sep 20 '22 14:09

Etan Reisner