#!/usr/bin/env bash # CONSTANTS DEBUG=true TMP_ERROR=$(mktemp -t "$(basename $0).XXXXXXXX" --tmpdir=/run/user/$(id -u)) SCRIPT=$1 # FUNCTIONS function return { builtin return ${1:-} } function exit { code=${1:-0} stack_lines=("${BASH_LINENO[@]}") stack_functions=("${FUNCNAME[@]}") stack_sources=("${BASH_SOURCE[@]}") unset stack_lines[-1] unset stack_lines[-1] unset stack_functions[0] unset stack_functions[-1] stack_functions[-1]='
' unset stack_sources[0] unset stack_sources[-1] stack_lines=("${stack_lines[@]}") stack_functions=("${stack_functions[@]}") stack_sources=("${stack_sources[@]}") if [[ -s $TMP_ERROR ]]; then last_error=$(tail -n1 $TMP_ERROR) $DEBUG && >/dev/tty echo '---stderr---' >&4 echo "ERROR $code: [$last_error]" fi for i in "${!stack_functions[@]}"; do >&4 printf "\t%30s\t%s\n" "${stack_sources[$i]}:${stack_lines[$i]}" "${stack_functions[$i]}" done # echo "${stack_lines[@]}" # echo "${stack_functions[@]}" # echo "${stack_sources[@]}" cleanup ${code} } function success { if [[ -s $TMP_ERROR ]]; then $DEBUG && >/dev/tty echo '---stderr---' >&2 cat $TMP_ERROR fi cleanup 0 } function cleanup { code=${1:-0} $DEBUG && >/dev/tty echo "---exit $1---" trap - ERR TERM INT EXIT rm $TMP_ERROR exec 3>&- 4>&- builtin exit $code } # MAIN set -TEue -o pipefail trap 'exit $?' ERR TERM INT EXIT # magic FD exec 3>$TMP_ERROR 4>/dev/stderr $DEBUG && >/dev/tty echo '---stdout---' source $SCRIPT 2>&3 success