[lug] How does bash "set -e" work?
Jeffrey S. Haemer
jeffrey.haemer at gmail.com
Sun Dec 30 11:22:04 MST 2012
Great puzzle. I saw this this morning, but couldn't dive into it because I
went to the Tanner all afternoon, then out to dinner and a movie. I was
certain someone else would have gotten to it before I returned, but maybe
you were all in the same bind. :-)
Much of the example is red herring. It's enough just to type, at a command
prompt, this pair:
$ (set -e; false; echo hello); echo $?
$ (set -e; false; echo subshell) || false; echo $?
In the first, the subshell fails, in the second, it succeeds.
The " || " is the culprit.
All the shells I have handy -- bash (with or without "--posix"), zsh, dash,
and the busybox shell (another ash variant) -- act this way. That's enough
for me to decide it's "correct" -- existing practice -- so my next question
is "What's the man page say about '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 ||*
Thus, if we swap the order, the subshell should fail, and exit after its
$ false || (set -e; false; echo subshell); echo $?
This looks like an un-intuitive manifestation of an actual, useful feature.
By reflex, I start my shell scripts with *#!/bin/bash -eux* which catches a
variety of coding errors I often make.
I want to be able to write code like this:
[ -d foo ] || mkdir foo
without having the whole script die at the "[ -d foo ]" if the directory
Does that really mean it should it ignore failures when the "set -e"
happens *within* a subshell in that list? *A priori*? Not obvious, at least
to me. But *de facto*? Looks like it's the traditional, if
Jeffrey Haemer <jeffrey.haemer at gmail.com>
720-837-8908 [cell], http://seejeffrun.blogspot.com [blog],
*פרייהייט? דאס איז יאַנג דינען וואָרט.*
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the LUG