-
-
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