Exiting from a shell script when a failure occurs

While debugging an issue with one of my scripts, I wanted to abort execution and exit when a non-zero return code occurred. I recalled reading about a bash flag that provided this behaviour, and after a few minutes of reading through bash(1) I came across the following set option:

“-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.”

So given the following test script that calls a non-existent command /bin/bork:

$ cat test
/bin/bork
echo “Made it after the bork”

We can see that a normal run completes to the end:

$ sh test
test: line 1: /bin/bork: No such file or directory
Made it after the bork

But an invocation with the “-e” option exits when a non-zero return value occurs:

$ sh -e test
test: line 1: /bin/bork: No such file or directory

The bash manual page is full of super interesting stuff, and I just printed it out to learn more! Nice!

2 Comments

Justin Ellison  on May 21st, 2009

That’s one I didn’t know about, and a great way to toggle a switch and make all lines in a shell script behave differently. For a little more control, you can use the && and || operators, like so:


#!/bin/bash
/bin/bork || exit 1
echo "Bork didn't fail"

&& does the opposite:

$!/bin/bash
/bin/bork && echo "Bork Succeeded"

David Phillips  on May 21st, 2009

Also handy:

“-u Treat unset variables as an error when performing parameter expansion. If expansion is attempted on an unset variable, the shell prints an error message, and, if not interactive, exits with a non-zero status.”

This lets you catch typos in variable names, rather than using the dangerous default of treating them as empty. I usually use “#!/bin/sh -eu” for shell scripts.

Another handy flag, great for debugging, is -x, which prints each command before executing it.

Leave a Comment