From 2a9b54deefc2d68fc20c046121e7ddd966131065 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Thu, 15 Jul 2021 15:37:15 -0400 Subject: [PATCH] print out variables in the failed command --- err | 63 +++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/err b/err index a5d3752..ff4c498 100644 --- a/err +++ b/err @@ -49,6 +49,10 @@ if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi # Note: In interactive shell, stack calling line number is not # available, so we print function definition lines. # +# Note: This works like set -e, which has one unintuitive feature: If +# you use a function as part of a conditional, eg: func && come_cmd, a +# failed command within func won't trigger an error. +# # Globals # # err_catch_ignore Array containing glob patterns to test against @@ -120,31 +124,67 @@ err-allow() { # ####################################### err-exit() { - local err=$? pipestatus="${PIPESTATUS[*]}" + # vars have _ prefix so that we can inspect existing set vars without + # too much overwriting of them. + local _err=$? _pipestatus="${_pipestatus[*]}" # This has to come before most things or vars get changed - local msg="${BASH_SOURCE[1]}:${BASH_LINENO[0]}: \`$BASH_COMMAND' returned $err" - if [[ $pipestatus != "$err" ]]; then - msg+=", PIPESTATUS: $pipestatus" + local _msg="${BASH_SOURCE[1]}:${BASH_LINENO[0]}: \`$BASH_COMMAND' returned $_err" + local _cmdr="$BASH_COMMAND" # command right. we chop of the left, keep the right. + + if [[ $_pipestatus != "$_err" ]]; then + _msg+=", PIPESTATUS: $_pipestatus" fi set +x if [[ $1 == -* ]]; then - err=${1#-} + _err=${1#-} shift - elif (( ! err )); then - err=1 + elif (( ! _err )); then + _err=1 fi if [[ $1 ]]; then - msg="$1" + _msg="$1" fi - printf "%s\n" "$msg" >&2 + + ## Begin printing vars from within BASH_COMMAND ## + local _var _chars _l + local -a _vars + while [[ $_cmdr ]]; do + _chars="${#_cmdr}" + _cmdr="${_cmdr#*$}" + _cmdr="${_cmdr#{}" + if [[ $_chars == ${#_cmdr} ]]; then + break + fi + _var="${_cmdr%%[^a-zA-Z0-9_]*}" + # debug: + #echo var = $_var _cmdr = $_cmdr + if [[ ! $_var || $_var == [0-9]* ]]; then + continue + fi + _vars+=("${_var}=*") + done + # in my small test, this took 50% longer than piping to grep. + # That seems a small enough penalty to stay in bash here. + if (( ${#_vars[@]} )); then + set |& while read -r _l; do + for _var in "${_vars[@]}"; do + if [[ $_l == $_var ]]; then + printf "%s\n" "$_l" >&2 + fi + done + done + fi + ## End printing vars from within BASH_COMMAND ## + + printf "%s\n" "$_msg" >&2 err-bash-trace 2 set -e # err trap does not work within an error trap if type -t err-cleanup >/dev/null; then err-cleanup fi - printf "%s: exiting with status %s\n" "$0" "$err" >&2 - exit $err + printf "%s: exiting with status %s\n" "$0" "$_err" >&2 + exit $_err } ####################################### @@ -251,4 +291,3 @@ _err-bash-trace-interactive() { return 0 fi } - -- 2.25.1