A gotcha with the Bourne shell's set -e and &&

July 7, 2010

Suppose that you have the following Bourne shell code:

set -e
cmd1 && cmd2 && cmd3
echo all done

Now suppose that cmd2 exits with a non-zero status. Do you expect the script to abort, or to print out 'all done'?

My assumption when I was writing a script recently was that the script would abort; after all, I had set -e turned on. But this is not what happens, and in fact most Bourne shell manpages spell it out explicitly; set -e only exits if what fails is a simple command that is not having its exit status tested. Everything except the final command in a series of &&'s is having its exit status tested, so failure of cmd2 here merely causes cmd3 not to be run.

(Different Bourne shell implementations use different wording about the exact conditions, but I suspect that they behave the same. See the Single Unix Specification description of set for perhaps the authoritative wording on it.)

If you are writing shell scripts, the immediate consequence of this is that it is not entirely safe to start out writing a script with various coded error checks and then later decide that you always want things to just exit on errors and add a set -e to handle it all; you may find that your script is not aborting when you want it to, or alternately that the script's failure to abort is quietly hiding the fact that a single command did fail and that something else didn't get run.

Written on 07 July 2010.
« How zpool status reports on ZFS scrubs and resilvers
Unix programs should avoid exiting non-zero for clever reasons »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Jul 7 18:45:56 2010
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.