# 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
#
#######################################
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
}
#######################################
return 0
fi
}
-