On Sat, 16 Dec 2023 at 07:21, Giacomo Comes <gco...@gmx.com> wrote:

> debugon () {
>     trap 'if (($?)); then echo "$((LINENO-1)): $(sed -n "$((LINENO-1))p"
> "$0")" ; fi' DEBUG
> }
> debugoff () {
>     trap '' DEBUG
> }
>
>
Although LINENO is the command that's about to be executed, that does not
imply that LINENO-1 is necessarily the line that contains the command just
executed, whose status is in $?.

It could be wrong if there's a loop or branch, or even just blank lines.
Another problem is that it doesn't tell you which file the line is in.

A better approach is to remember the current line and then use that during
the next trap, perhaps something more like this:

# adjust to taste, especially if you like colour
debug_fmt='%-3u %s:%u %.40s\n'
debug_file=$BASH_SOURCE
debug_line=$LINENO

debugtrace() {
    local e=$?
    if ((e)) ; then
        read -r debug_command < <( tail -n +$debug_line < "$debug_file" )
        printf >&2 "$debug_fmt" "$e" \
                "${debug_file##*/}" \
                "$debug_line" \
                "$debug_command"
    fi
    IFS=' ' read debug_line debug_file < <( caller )
}
debugon() { trap debugtrace DEBUG; }
debugoff() { trap '' DEBUG; }

-Martin

Reply via email to