diff --git a/lib/backtrace.bash b/lib/backtrace.bash index 93d7f4a..a16dd40 100644 --- a/lib/backtrace.bash +++ b/lib/backtrace.bash @@ -21,11 +21,13 @@ function exit { # # remove 0 on tail list # [[ ${#stack_lines[@]} > 0 && ${stack_lines[-1]} == 0 ]] && unset stack_lines[-1] + rm $script if [[ $error_code > 0 ]]; then printf "\nEXIT #${error_code} due to error at line ${stack_lines[*]} : \n-----------------------------------------\n" - echo "FUNCNAME: ${FUNCNAME[@]}" >&2 # inner outer main - echo "BASH_SOURCE: ${BASH_SOURCE[@]}" >&2 - echo "BASH_LINENO: ${BASH_LINENO[@]}" >&2 + [[ -s /tmp/error ]] && echo -ne 'CAUSE:\t\t' && cat /tmp/error + echo -e "FUNCNAME:\t${FUNCNAME[@]}" >&2 # inner outer main + echo -e "BASH_SOURCE:\t${BASH_SOURCE[@]}" >&2 + echo -e "BASH_LINENO:\t${BASH_LINENO[@]}" >&2 trap - ERR TERM INT EXIT builtin exit "${error_code}" else @@ -41,8 +43,11 @@ function raise_error { exit $code } +# MAIN _BACKTRACE=${_BACKTRACE:-false} # echo "_BACKTRACE=${_BACKTRACE}" + +# a bit of magic: preserve performing the original script and rather running the backtrace version ${_BACKTRACE} && return set -TEue @@ -50,5 +55,23 @@ trap 'exit $?' ERR TERM INT EXIT # echo "current: ${BASH_SOURCE[-1]}" # echo "ARGV : $@" export _BACKTRACE=true -# exec ${BASH_SOURCE[-1]} $* -eval $(<${BASH_SOURCE[-1]}) $* + +source=${BASH_SOURCE[-1]} +script="${source}.backtrace" +cp $source $script + +# prepend the set Strict command +sed -i '1s/.*/set -TEue/' $script + +# a bit of magic: save stderr into /tmp/error while outputing stdout! +{ + $script 3>&1 1>&2 2>&3 | tee /tmp/error +} 2>/dev/null >/dev/null + +# SOME VARIANTS (which does not work actually) +# ---------- +# exec ${BASH_SOURCE[-1]} $* 2>/tmp/error +# eval $(<${BASH_SOURCE[-1]}) $* 2>/tmp/error +# eval $(<$script) $* 2>&1 >/tmp/error +# $script $* 2>&1 >>/tmp/error +# ERROR=$($script 3>&1 1>&2 2>&3 | tee /tmp/error) diff --git a/test2.sh b/test2.sh new file mode 100755 index 0000000..d34f654 --- /dev/null +++ b/test2.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env -S -- bash + +## MAIN +. "lib/backtrace.bash" + +function f1 { + echo START f1 + # return 4 + # echo $nope + grep titi titi + grep titi titi 2>/dev/null + false + echo END F1 +} + +echo START test2 +f1 +echo END test2