proper way to detect shell exit code when errexit option set

How about this? If you want the actual exit code ...

#!/bin/sh                                                                       
set -e

cat /tmp/doesnotexist && rc=$? || rc=$?                                         
echo exitcode: $rc        

cat /dev/null && rc=$? || rc=$?                                                 
echo exitcode: $rc   

Output:

cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0

Keep with errexit. It can help find bugs that otherwise might have unpredictable (and hard to detect) results.

#!/bin/bash
set -o errexit ; set -o nounset

bad_command || do_err_handle
good_command

The above will work fine. errexit only requires that the line pass, as you do with the bad_command && rc=0. Therefore, the above with the 'or' will only run do_err_handle if bad_command fails and, as long as do_err_handle doesn't also 'fail', then the script will continue.


Continue to write solid shell code.

You do it right if bad_command is really a command. But be careful with function calls in if, while, ||, && or !, because errexit will not work there. It may be dangerous.

If your bad_command is actually bad_function you should write this:

set -eu 

get_exit_code() {
    set +e
    ( set -e;
      "$@"
    )
    exit_code=$?
    set -e
}

...

get_exit_code bad_function

if [ "$exit_code" != 0 ]; then
    do_err_handle
fi

This works well in bash 4.0. In bash 4.2 you only get exit codes 0 or 1.

Tags:

Shell