-
-
Save ahendrix/7030300 to your computer and use it in GitHub Desktop.
| function errexit() { | |
| local err=$? | |
| set +o xtrace | |
| local code="${1:-1}" | |
| echo "Error in ${BASH_SOURCE[1]}:${BASH_LINENO[0]}. '${BASH_COMMAND}' exited with status $err" | |
| # Print out the stack trace described by $function_stack | |
| if [ ${#FUNCNAME[@]} -gt 2 ] | |
| then | |
| echo "Call tree:" | |
| for ((i=1;i<${#FUNCNAME[@]}-1;i++)) | |
| do | |
| echo " $i: ${BASH_SOURCE[$i+1]}:${BASH_LINENO[$i]} ${FUNCNAME[$i]}(...)" | |
| done | |
| fi | |
| echo "Exiting with status ${code}" | |
| exit "${code}" | |
| } | |
| # trap ERR to provide an error handler whenever a command exits nonzero | |
| # this is a more verbose version of set -o errexit | |
| trap 'errexit' ERR | |
| # setting errtrace allows our ERR trap handler to be propagated to functions, | |
| # expansions and subshells | |
| set -o errtrace |
What is the purpose of line 4: local code="${1:-1}" ? It seems like $1 will never be set, so $code will always be simply 1.
@parke it's been almost a decade since I wrote this, so my memory is a little fuzzy.
I think there might have been cases where I called the error handler directly instead of through the trap in a few places, particularly if I wanted a stack trace but didn't want my script to exit.
@trainman419 I have discovered one reason you might want to receive codes via $1. Namely, so you can send multiple traps to the same handler, yet distinguish between them. For example:
trap 'errexit ERR ' ERR
trap 'errexit TERM' TERM
Relatedly, you might want to do the following:
trap 'errexit ' ERR
trap 'errexit 1' TERM
The reason is that on ERR, $? will be non-zero. However on SIGTERM, $? will be zero. So if you want to exit with non-zero on a trap of SIGTERM, that non-zero value needs to come from somewhere other than $?.
On any error print full stack trace of the failure and exit with the original error code
https://gist.github.com/moisei/4cb326101eae1d9d07244cfd9ee2ef5a