When to use set -e
Yes, you should always use it. People make fun of Visual Basic all the time, saying it's not a real programming language, partly because of its “On Error Resume Next” statement. Yet that is the default in shell! set -e
should have been the default. The potential for disaster is just too high.
In places where it's ok for a command to fail, you can use || true
or its shortened form ||:
, e.g.
grep Warning build.log ||:
In fact you should go a step further, and have
set -eu
set -o pipefail
at the top of every bash
script.
-u
makes it an error to reference a non-existent environment variable such as ${HSOTNAME}
, at the cost of requiring some gymnastics with checking ${#}
before you reference ${1}
, ${2}
, and so on.
pipefail
makes things like misspeled-command | sed -e 's/^WARNING: //'
raise errors.
If your script code checks for errors carefully and properly where necessary, and handles them in an appropriate manner, then you probably don't ever need or want to use set -e
.
On the other hand if your script is a simple sequential list of commands to be run one after another, and if you want the script to terminate if any one of those fail, then sticking set -e
at the top would be exactly what you would want to do to keep your script simple and uncluttered. A perfect example of this would be if you're creating a script to compile a set of sources and you want the compile to stop after the first file with errors is encountered.
More complex scripts can combine these methods since you can use set +e
to turn its effect back off again and go back to explicit error checking.
Note that although set -e
is supposed to cause the shell to exit IFF any untested command fails, it is wise to turn it off again when your code is doing its own error handling as there can easily be weird cases where a command will return a non-zero exit status that you're not expecting, and possibly even such cases that you might not catch in testing, and where sudden fatal termination of your script would leave something in a bad state. So, don't use set -e
, or leave it turned on after using it briefly, unless you really know that you want it.
Note also that you can still define an error handler with trap ERR
to do something on an error condition when set -e
is in effect, as that will still be run before the shell exits.