Skip to content
TURNKEYGNU / LINUX
AppsDocumentationBlogScreenshotsGitHubTurnKey Hub
文English
EnglishDeutschEspañol日本語Português中文
Home/Blog/Two simple tricks for better shell script error handling

From the project

Two simple tricks for better shell script error handling

By Liraz SiriApril 5, 20102 min read
developmentshell

Psssst. Hey you... yeah you. Word on the street is your shell scripts don't do any error handling. They just chug happily along even when everything is broken.

Because a lowly shell shell script doesn't need any error handling right? WRONG!

Here are two simple tricks that are easy to use and will make your scripts much more robust.

  1. Turn on -e mode (do you feel lucky - punk?)

    In this mode any command your script runs which returns a non-zero exitcode - an error in the world of shell - will cause your script to itself terminate immediately with an error.

    You can do that in your shebang line:

    #!/bin/sh -e
    

    Or using set:

    set -e
    

    Yes, this is what you want. A neat predictable failure is infinitely better than a noisy unreliable failure.

    If you REALLY want to ignore an error, be explicit about it:

    # I don't care if evil-broken-command fails
    evil-broken-command || true
    

    Oh and as long as you're messing with shell modes, -e goes well with -x (which I like to think of as shell X-ray).

    Like this:

    #!/bin/sh -ex
    

    Or like this:

    # turn -x on if DEBUG is set to a non-empty string
    [ -n "$DEBUG" ] && set -x
    

    That way you can actually see what your script was doing right before it failed.

  2. Use trap for robust clean-ups

    A trap is a snippet of code that the shell executes when it exits or receives a signal. For example, pressing CTRL-C in the terminal where the script is running generates the INT signal. killing the process by default generates a TERM (I.e., terminate) signal.

    I find traps most useful for making sure my scripts clean-up after themselves whatever happens (e.g., a non-zero error code in -e mode).

    For example:

    
    #!/bin/sh -e
    
    TMPFILE=$(tempfile)
    trap 'echo "removing $TMPFILE"; rm -f $TMPFILE' INT TERM EXIT
    
    echo TMPFILE=$TMPFILE
    echo hello world > $TMPFILE
    cat $TMPFILE
    
    # gives user a chance to press CTRL-C
    sleep 3
    
    # false always returns an error
    false
    
    echo "NEVER REACHED"
    

    Note that you can only set one trap per signal. If you set a new trap you're implicitly disabling the old one. You can also disable a trap by specifying - as the argument, like this:

    trap - INT TERM EXIT
    

Comments (1)

In shell, return code 0 is true

Reply 1 2016-09-03
Kind of weird but it's true. Non zero return values are considered errors. Zero is good.

Keep exploring

Find your next server

Browse ready-to-use appliances by the job you need to do.

Explore the app library
TURNKEYGNU / LINUX

Own your infrastructure without starting from scratch.

Explore TurnKey
AboutDocumentationFAQBlogGitHub
Free and open sourceSecure by defaultReady to deploy