From edeaee142925c32c10e61b2da38b43d2dee92d15 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Sat, 14 Feb 2026 07:03:31 -0500 Subject: [PATCH] add func for just reporting errors, eg for a best-effort service --- bash-bear | 104 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 36 deletions(-) diff --git a/bash-bear b/bash-bear index 611d604..9c3ead1 100644 --- a/bash-bear +++ b/bash-bear @@ -161,7 +161,7 @@ err-allow() { } ####################################### -# err-exit: Print stack trace and exit +# err-exit: Print last command info, stack trace, then exit # # Use this instead of the exit command to be more informative. # @@ -183,11 +183,8 @@ err-exit() { # This has to come before most things or vars get changed 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. + local _cmdr="$BASH_COMMAND" # command right. we chop off the left, keep the right. - if [[ -v _pipestatus && $_pipestatus && $_pipestatus != "$_err" ]]; then - _msg+=", PIPESTATUS: $_pipestatus" - fi set +x if [[ $# -ge 1 && $1 == -* ]]; then _err="${1#-}" @@ -199,38 +196,8 @@ err-exit() { _msg="$1" fi - ## 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_]*}" - if [[ ! $_var || $_var == [0-9]* ]]; then - continue - fi - _vars[${_var}]=t - done - #echo "iank ${_vars[*]}" - #set |& grep ^password - # 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 - case $_l in - ${_var}=*) printf "%s\n" "$_l" >&2 ;; - esac - done - done - fi - ## End printing vars from within BASH_COMMAND ## + _err-bash-print-command-info - printf "%s\n" "$_msg" >&2 err-bash-trace 2 set -e # err trap does not work within an error trap @@ -242,6 +209,27 @@ err-exit() { exit $_err } +####################################### +# err-info: Print last command info & stack trace +# +# Like err-exit but without the exit. +# +# usage: After sourcing this file, trap err-info ERR +# +####################################### +err-info() { + local _err=$? _pipestatus="${PIPESTATUS[*]}" + + # note: duplicated in err-exit + local _msg="${BASH_SOURCE[1]}:${BASH_LINENO[0]}: \`$BASH_COMMAND' returned $_err" + local _cmdr="$BASH_COMMAND" + + set +x + _err-bash-print-command-info + err-bash-trace 2 + +} + ####################################### # Print stack trace # @@ -285,6 +273,50 @@ err-bash-trace() { return 0 } +####################################### +# Internal function for err-exit & err-info. +# +# Usage: see calling functions +####################################### +_err-bash-print-command-info() { + if [[ -v _pipestatus && $_pipestatus && $_pipestatus != "$_err" ]]; then + _msg+=", PIPESTATUS: $_pipestatus" + fi + + ## 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_]*}" + if [[ ! $_var || $_var == [0-9]* ]]; then + continue + fi + _vars[${_var}]=t + done + #echo "iank ${_vars[*]}" + #set |& grep ^password + # 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 + case $_l in + ${_var}=*) printf "%s\n" "$_l" >&2 ;; + esac + done + done + fi + ## End printing vars from within BASH_COMMAND ## + + printf "%s\n" "$_msg" >&2 +} + ####################################### # Internal function for err-catch. Prints stack trace from interactive # shell trap. -- 2.25.1