79629279

Date: 2025-05-19 18:27:22
Score: 1
Natty:
Report link

@EdMorton Thanks a lot, you are the best! :)

So I got this now and it seems to work well:

set -E

trap 'trap_err' ERR

export -a DEBUG_STACK_LAST=()

trap_err() {
    local -n a=DEBUG_STACK_LAST
    local -n b=BASH_LINENO

    local -i is_substack=0
    ((${#a[@]} == ${#b[@]}+1)) && { is_substack=1; for i in ${!b[@]}; do
        ((${a[$((i+1))]} != ${b[$i]})) && is_substack=0 && break
    done; }

    a=(${b[@]})

    ((is_substack == 1)) && return

    echo "D: $BASH_COMMAND . ${FUNCNAME[@]:1} . ${BASH_LINENO[@]}"
}

I have to test more cases, but I made a new test scenario:

f() {
    echo "* $FUNCNAME here: $@"
    stat /from/f
}

g() {
    echo "* $FUNCNAME here: $@"
    stat /from/g ||:
}

h() {
    echo "* $FUNCNAME here: $@"
    f "$@ ~ from h"
    g "$@ ~ from h"
}

echo; echo "** functions"

f round 1
g round 1
h round 1

echo; echo "** subshells"

(f round 2)
(g round 2)
(h round 2)

echo; echo "** plain"

stat /from/main ||:

What I particularly like is that if the ERR trapped call from a subshell, I get to see it (duplicate), but I do not get to see the extras from diving down the stack. Here:

** functions
* f here: round 1
stat: cannot statx '/from/f': No such file or directory
D: stat /from/f . f main . 27 44 0
* g here: round 1
stat: cannot statx '/from/g': No such file or directory
* h here: round 1
* f here: round 1 ~ from h
stat: cannot statx '/from/f': No such file or directory
D: stat /from/f . f h main . 27 38 46 0
* g here: round 1 ~ from h
stat: cannot statx '/from/g': No such file or directory

** subshells
* f here: round 2
stat: cannot statx '/from/f': No such file or directory
D: stat /from/f . f main . 27 50 0
D: ( f round 2 ) . main . 50 0
* g here: round 2
stat: cannot statx '/from/g': No such file or directory
* h here: round 2
* f here: round 2 ~ from h
stat: cannot statx '/from/f': No such file or directory
D: stat /from/f . f h main . 27 38 52 0
* g here: round 2 ~ from h
stat: cannot statx '/from/g': No such file or directory

** plain
stat: cannot statx '/from/main': No such file or directory

I never see the same stat command twice, but I do get to see D: ( f round 2 ) . main . 50 0 as an extra there. I think it's actually better than NOT showing it. I feel it's very little extra work for getting your PoC robust.

Reasons:
  • Blacklisted phrase (0.5): Thanks
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @EdMorton
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Albert Camu