Search code examples
bashshexit-codeexitstatus

How to tell if any command in bash script failed (non-zero exit status)


I want to know whether any commands in a bash script exited with a non-zero status.

I want something similar to set -e functionality, except that I don't want it to exit when a command exits with a non-zero status. I want it to run the whole script, and then I want to know that either:

a) all commands exited with exit status 0
-or-
b) one or more commands exited with a non-zero status


e.g., given the following:

#!/bin/bash

command1  # exits with status 1
command2  # exits with status 0
command3  # exits with status 0

I want all three commands to run. After running the script, I want an indication that at least one of the commands exited with a non-zero status.


Solution

  • Set a trap on ERR:

    #!/bin/bash
    
    err=0
    trap 'err=1' ERR
    
    command1
    command2
    command3
    test $err = 0 # Return non-zero if any command failed
    

    You might even throw in a little introspection to get data about where the error occurred:

    #!/bin/bash
    for i in 1 2 3; do
            eval "command$i() { echo command$i; test $i != 2; }"
    done
    
    err=0
    report() {
            err=1
            printf '%s' "error at line ${BASH_LINENO[0]}, in call to "
            sed -n ${BASH_LINENO[0]}p $0
    } >&2
    trap report ERR
    
    command1
    command2
    command3
    exit $err