Skip to content

Instantly share code, notes, and snippets.

@ahendrix
Created October 17, 2013 18:56
Show Gist options
  • Star 56 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save ahendrix/7030300 to your computer and use it in GitHub Desktop.
Save ahendrix/7030300 to your computer and use it in GitHub Desktop.
bash stacktrace
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
@parke
Copy link

parke commented Oct 6, 2022

@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 $?.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment