Skip to content

Instantly share code, notes, and snippets.

@dvishniakov
Forked from ahendrix/gist:7030300
Last active October 5, 2020 21:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dvishniakov/86c83ef891d200674522c791589d42b3 to your computer and use it in GitHub Desktop.
Save dvishniakov/86c83ef891d200674522c791589d42b3 to your computer and use it in GitHub Desktop.
bash stacktrace
#!/usr/bin/env bash
#from https://gist.github.com/dvishniakov/86c83ef891d200674522c791589d42b3
# Provides stack trace when error occurs or when manually called
# $1 is message
# $2 is command
# ${ContinueOnErrors} controls whether to continue or stop script if error is catched.
# it helps during batch processing. -o errexit/errtrace also affects this
errexit() {
local errno=$? # non-zero when this function is called via trap
local bashopts=$-
set +o xtrace # disabling debugging commands so output of this function will be clear
echo "Error in ${BASH_SOURCE[1]}:${BASH_LINENO[0]}: '${@:2}' exited with code ${errno}: '${1}'">&2
# Print out the stack trace described by $function_stack
if [ ${#FUNCNAME[@]} -gt 2 ]; then
echo "Call tree:">&2
for ((i=1;i<${#FUNCNAME[@]}-1;i++)); do
echo " $i: ${BASH_SOURCE[$i+1]}:${BASH_LINENO[$i]} ${FUNCNAME[$i]}(...)">&2
done
fi
set -${bashopts} # restoring options
[ -n "${ContinueOnErrors-}" ] || exit "${errno:-1}"
}
# trap ERR to provide an error handler whenever a command exits nonzero
# this is a more verbose version of set -o errexit
trap 'errexit "Trap catched" "${BASH_COMMAND}"' ERR
# setting errtrace(-E) allows our ERR trap handler to be propagated to functions,
# expansions and subshells
# nounset(-u): error on expand of unset variable
# pipefail: if a piped command fails, it's error code is returned as error code of the whole pipeline
# errexit(-e): exit when command returns with an error. Just in case if something happens with the trap
set -o errtrace -o nounset -o pipefail -o errexit
# # examples
# # just test conditions and error will be trapped
# [ -n "" ]
# # or provide meaningful parameters yourself. Not clear how to get that [ -z "${BASH_SOURCE}" ] as a second parameter
# [ -z "${BASH_SOURCE}" ] || errexit "Empty value" "-z BASH_SOURCE"
# cd somewhere
# testFn() {
# [ -n "${4:-}" ] || errexit "Not enough arguments" "$FUNCNAME $@"
# cd somewhere
# }
# testFn 1 2 3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment