set -E;
# This condition avoids starting the bash debugger in the case that
# this is sourced from a startup file, and you use a login shell to
- # run a command. Avoid doing that if you want function arguments in
- # your trace.
- if [[ $- != *c* ]] || ! shopt login_shell >/dev/null; then
+ # run a command. eg: bash -l some-command. Avoid doing that if you want
+ # function arguments in your trace.
+ if ! shopt login_shell >/dev/null; then
shopt -s extdebug
fi
_err-trap() {
#######################################
_err-bash-trace-interactive() {
- local ret bash_command argc pattern i
+ local ret bash_command argc pattern i last
+ last=$_err_func_last
+ _err_func_last=${#FUNCNAME[@]}
+ if (( _err_func_last <= 1 )); then
+ return 0
+ fi
# We have these passed to us because they are lost inside the
# function.
ret=$1
argv=("$@")
for pattern in "${err_catch_ignore[@]}"; do
# shellcheck disable=SC2053
- if [[ ${BASH_SOURCE[0]} == $pattern ]]; then
+ if [[ ${BASH_SOURCE[1]} == $pattern ]]; then
return 0
fi
done
- if (( ${#FUNCNAME[@]} > _err_func_last )); then
+ # The trap returns a nonzero, then gets called again. This condition
+ # tells us if we are the first.
+ if (( _err_func_last > last )); then
echo ERR: \`$bash_command\' returned $ret
fi
- _err_func_last=${#FUNCNAME[@]}
- if (( _err_func_last > 1 )); then
- printf " from \`%s" "${FUNCNAME[1]}"
- if shopt extdebug >/dev/null; then
- for ((i=argc; i >= 0; i--)); do
- printf " %s" "${argv[i]}"
- done
- fi
- printf "\' defined at %s:%s\n" "${BASH_SOURCE[1]}" "$(declare -F "${FUNCNAME[1]}"|awk "{print \$2}")"
- return $ret
+ printf " from \`%s" "${FUNCNAME[1]}"
+ if shopt extdebug >/dev/null; then
+ for ((i=argc; i >= 0; i--)); do
+ printf " %s" "${argv[i]}"
+ done
fi
+ printf "\' defined at %s:%s\n" "${BASH_SOURCE[1]}" "$(declare -F "${FUNCNAME[1]}"|awk "{print \$2}")"
+ return $ret
}
#######################################
declare -i _err_func_last=0
set -E; shopt -s extdebug
# shellcheck disable=SC2154
- trap '_err-bash-trace-interactive $? "$BASH_COMMAND" ${BASH_ARGC[0]} "${BASH_ARGV[@]}"' ERR
+ trap '_err-bash-trace-interactive $? "$BASH_COMMAND" ${BASH_ARGC[0]} "${BASH_ARGV[@]}" || return $?' ERR
set -o pipefail
}