|
|
|
@ -2,15 +2,16 @@ |
|
|
|
|
|
|
|
# CONSTANTS |
|
|
|
|
|
|
|
BASH_BACK_ERROR=$(mktemp -t "$(basename "$0").XXXXXXXX" --tmpdir="/run/user/$(id -u)") |
|
|
|
BASH_BACK_DEBUG=${BASH_BACK_DEBUG:-false} |
|
|
|
readonly BASH_BACK_ERROR BASH_BACK_DEBUG |
|
|
|
MIAOU_BASH_ERROR=$(mktemp -t "$(basename "$0").XXXXXXXX" --tmpdir="/run/user/$(id -u)") |
|
|
|
MIAOU_BASH_DEBUG=${MIAOU_BASH_DEBUG:-false} |
|
|
|
readonly MIAOU_BASH_ERROR MIAOU_BASH_DEBUG |
|
|
|
|
|
|
|
# FUNCTIONS |
|
|
|
|
|
|
|
function on_return { |
|
|
|
# regex does not work here unfortunately! |
|
|
|
if [[ "${BASH_COMMAND}" == 'return '* ]]; then |
|
|
|
code=$(echo "${BASH_COMMAND}" | cut -d' ' -f2) # regex does not work here unfortunately! |
|
|
|
code=$(echo "${BASH_COMMAND}" | cut -d' ' -f2) |
|
|
|
if [[ -n "$code" ]] && [[ "$code" -ne 0 ]]; then |
|
|
|
trap - DEBUG |
|
|
|
>&2 echo "${BASH_SOURCE[2]}: line ${BASH_LINENO[0]}: return $code from ${FUNCNAME[1]}" |
|
|
|
@ -55,7 +56,7 @@ function on_exit { |
|
|
|
stack_summary=() |
|
|
|
|
|
|
|
if [[ $code -gt 0 ]]; then |
|
|
|
last_error=$(tail -n1 "$BASH_BACK_ERROR") |
|
|
|
last_error=$(tail -n1 "$MIAOU_BASH_ERROR") |
|
|
|
last_source=${stack_sources[0]} |
|
|
|
last_source=${last_source//./"\."} # replace '.' with '\.' |
|
|
|
regex1="^$last_source: line ([0-9]+): (.*)\$" |
|
|
|
@ -87,44 +88,44 @@ function on_exit { |
|
|
|
stack_detail=$(printf "\t%30s\t%s\n" "${stack_sources[$i]}:${stack_lines[$i]}" "${stack_functions[$i]}") |
|
|
|
stack_summary+=("$stack_detail") |
|
|
|
done |
|
|
|
>&4 dump_stderr true |
|
|
|
dump_summary |
|
|
|
dump_failure |
|
|
|
else |
|
|
|
>&4 dump_stderr false |
|
|
|
dump_success |
|
|
|
fi |
|
|
|
|
|
|
|
cleanup |
|
|
|
builtin exit "$code" |
|
|
|
} |
|
|
|
|
|
|
|
function dump_summary { |
|
|
|
$BASH_BACK_DEBUG && >/dev/tty echo '---stacktrace---' |
|
|
|
function dump_failure { |
|
|
|
dump_stderr true |
|
|
|
$MIAOU_BASH_DEBUG && >/dev/tty echo '---stacktrace---' |
|
|
|
for i in "${stack_summary[@]}"; do |
|
|
|
>&4 echo -e "$i" |
|
|
|
done |
|
|
|
cleanup |
|
|
|
} |
|
|
|
|
|
|
|
function dump_stderr { |
|
|
|
last_trim=${1:-false} |
|
|
|
mapfile -t tmp_error <"$BASH_BACK_ERROR" |
|
|
|
mapfile -t tmp_error <"$MIAOU_BASH_ERROR" |
|
|
|
$last_trim && unset 'tmp_error[-1]' && tmp_error=("${tmp_error[@]}") |
|
|
|
if [[ "${#tmp_error[@]}" -gt 0 ]]; then |
|
|
|
$BASH_BACK_DEBUG && >/dev/tty echo '---stderr---' |
|
|
|
$MIAOU_BASH_DEBUG && >/dev/tty echo '---stderr---' |
|
|
|
for i in "${tmp_error[@]}"; do |
|
|
|
echo -e "$i" |
|
|
|
>&4 echo -e "$i" |
|
|
|
done |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
function success { |
|
|
|
>&2 dump_stderr |
|
|
|
function dump_success { |
|
|
|
dump_stderr |
|
|
|
cleanup |
|
|
|
} |
|
|
|
|
|
|
|
function cleanup { |
|
|
|
trap - ERR TERM INT EXIT |
|
|
|
exec 3>&- 4>&- |
|
|
|
rm "$BASH_BACK_ERROR" |
|
|
|
rm "$MIAOU_BASH_ERROR" |
|
|
|
} |
|
|
|
|
|
|
|
# MAIN |
|
|
|
@ -136,10 +137,10 @@ trap 'on_exit $?' ERR TERM INT EXIT |
|
|
|
trap 'on_return' DEBUG |
|
|
|
BASH_ARGV0="$1" && shift # to pretend script runs by itself |
|
|
|
|
|
|
|
# magic FD + delayed tee => /dev/fd/3 means delayed stderr, /dev/fd/4 remains stderr |
|
|
|
exec 3> >(tee "$BASH_BACK_ERROR" >/dev/null) 4>/dev/stderr |
|
|
|
# magic FD + delayed tee => /dev/fd/3 means delayed stderr, /dev/fd/4 remains original stderr |
|
|
|
exec 3> >(tee "$MIAOU_BASH_ERROR" >/dev/null) 4>/dev/stderr |
|
|
|
|
|
|
|
$BASH_BACK_DEBUG && >/dev/tty echo '---stdout---' |
|
|
|
$MIAOU_BASH_DEBUG && >/dev/tty echo '---stdout---' |
|
|
|
# shellcheck source=/dev/null |
|
|
|
source "$BASH_ARGV0" 2>&3 |
|
|
|
success |
|
|
|
dump_success |