-
-
Save dghodgson/42eed0944ca9308dd6ee7b4b07e67bdd to your computer and use it in GitHub Desktop.
A template showing how to do bash tracebacks. This makes using `set -eu` much more comfortable.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Tracebacks in bash | |
# https://docwhat.org/tracebacks-in-bash/ | |
# | |
# Just take the code between the "cut here" lines | |
# and put it in your own program. | |
# | |
# Written by Christian Höltje | |
# Donated to the public domain in 2013 | |
set -eu | |
trap _exit_trap EXIT | |
trap _err_trap ERR | |
_showed_traceback=f | |
function _exit_trap | |
{ | |
local _ec="$?" | |
if [[ $_ec != 0 && "${_showed_traceback}" != t ]]; then | |
traceback 1 | |
fi | |
} | |
function _err_trap | |
{ | |
local _ec="$?" | |
local _cmd="${BASH_COMMAND:-unknown}" | |
traceback 1 | |
_showed_traceback=t | |
echo "The command ${_cmd} exited with exit code ${_ec}." 1>&2 | |
} | |
function traceback | |
{ | |
# Hide the traceback() call. | |
local -i start=$(( ${1:-0} + 1 )) | |
local -i end=${#BASH_SOURCE[@]} | |
local -i i=0 | |
local -i j=0 | |
echo "Traceback (last called is first):" 1>&2 | |
for ((i=start; i < end; i++)); do | |
j=$(( i - 1 )) | |
local function="${FUNCNAME[$i]}" | |
local file="${BASH_SOURCE[$i]}" | |
local line="${BASH_LINENO[$j]}" | |
echo " ${function}() in ${file}:${line}" 1>&2 | |
done | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
source traceback.sh | |
######## | |
## Demos | |
function bomb | |
{ | |
trap _err_trap ERR | |
local limit=${1:-5} | |
echo -n " ${limit}" | |
if [ "${limit}" -le 0 ]; then | |
echo " BOOM" | |
return 10 | |
else | |
bomb $(( limit - 1 )) | |
fi | |
} | |
function stack | |
{ | |
stack_1 | |
} | |
function stack_1 | |
{ | |
stack_2 | |
} | |
function stack_2 | |
{ | |
stack_3 | |
} | |
function stack_3 | |
{ | |
no_such_function | |
} | |
####### | |
## Main | |
case "${1:-}" in | |
stack) | |
stack;; | |
bomb) | |
echo -n "Counting down..."; bomb ;; | |
badvar) | |
echo "This shouldn't be shown because ${bad_variable} isn't set";; | |
false) | |
false;; | |
true) | |
true;; | |
*) | |
echo "Usage: $0 [bomb|badvar|true|false|stack]" | |
;; | |
esac | |
# EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Makes more sense to split and source. Could put in
/usr/local/lib
?