Error handling in Bash

bash, error-handling, error-logging, scripting

Solution

Use a trap!

tempfiles=( )
cleanup() {
  rm -f "${tempfiles[@]}"
}
trap cleanup 0

error() {
  local parent_lineno="$1"
  local message="$2"
  local code="${3:-1}"
  if [[ -n "$message" ]] ; then
    echo "Error on or near line ${parent_lineno}: ${message}; exiting with status ${code}"
  else
    echo "Error on or near line ${parent_lineno}; exiting with status ${code}"
  fi
  exit "${code}"
}
trap 'error ${LINENO}' ERR

...then, whenever you create a temporary file:

temp_foo="$(mktemp -t foobar.XXXXXX)"
tempfiles+=( "$temp_foo" )

and `$temp_foo` will be deleted on exit, and the current line number will be printed. (`set -e` will likewise give you exit-on-error behavior, though it comes with serious caveats and weakens code's predictability and portability).

You can either let the trap call `error` for you (in which case it uses the default exit code of 1 and no message) or call it yourself and provide explicit values; for instance:

error ${LINENO} "the foobar failed" 2

will exit with status 2, and give an explicit message.

Alternatively `shopt -s extdebug` and give the first lines of the trap a little modification to trap all non-zero exit codes across the board (mind `set -e` non-error non-zero exit codes):

error() {
  local last_exit_status="$?"
  local parent_lineno="$1"
  local message="${2:-(no message ($last_exit_status))}"
  local code="${3:-$last_exit_status}"
  # ... continue as above
}
trap 'error ${LINENO}' ERR
shopt -s extdebug

This then is also "compatible" with `set -eu`.

Problem

What is your favorite method to handle errors in Bash? The best example of handling errors I have found on the web was written by William Shotts, Jr at http://www.linuxcommand.org. He suggests using the following function for error handling in Bash: ``` #!/bin/bash # A slicker error handling routine # I put a variable in my scripts named PROGNAME which # holds the name of the program being run. You can get this # value from the first item on the command line ($0). # Reference: This was copied from <http://www.linuxcommand.org/wss0150.php> PROGNAME=$(basename $0) function error_exit { # ---------------------------------------------------------------- # Function for exit due to fatal program error # Accepts 1 argument: # string containing descriptive error message # ---------------------------------------------------------------- echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2 exit 1 } # Example call of the error_exit function. Note the inclusion # of the LINENO environment variable. It contains the current # line number. echo "Example of error with line number and message" error_exit "$LINENO: An error has occurred." ``` Do you have a better error handling routine that you use in Bash scripts?

Original source

Related problems