Bash:如何在错误上获得调用链?

Nei*_*ill 7 bash

我在bash中有一个后跟踪功能,运行良好(下面的代码),但问题是当它遇到错误时bash本身,它没有给出回溯或任何有助于确定调用者的信息,可以帮助调试问题.

例如:

./c.sh:line 23:urgh:找不到命令

function backtrace () {
    local deptn=${#FUNCNAME[@]}

    for ((i=1; i<$deptn; i++)); do
        local func="${FUNCNAME[$i]}"
        local line="${BASH_LINENO[$((i-1))]}"
        local src="${BASH_SOURCE[$((i-1))]}"
        printf '%*s' $i '' # indent
        echo "at: $func(), $src, line $line"
    done
}
Run Code Online (Sandbox Code Playgroud)

是否有可能在这些错误上捕获bash所以我可以调用自己的函数来获得这样的输出?

 at: c(), ./c.sh, line 22
  at: b(), ./c.sh, line 11
   at: main(), ./b.sh, line 5
Run Code Online (Sandbox Code Playgroud)

更新:建议和跟踪陷阱的最终工作版本出错:

function backtrace () {
    local deptn=${#FUNCNAME[@]}

    for ((i=1; i<$deptn; i++)); do
        local func="${FUNCNAME[$i]}"
        local line="${BASH_LINENO[$((i-1))]}"
        local src="${BASH_SOURCE[$((i-1))]}"
        printf '%*s' $i '' # indent
        echo "at: $func(), $src, line $line"
    done
}

function trace_top_caller () {
    local func="${FUNCNAME[1]}"
    local line="${BASH_LINENO[0]}"
    local src="${BASH_SOURCE[0]}"
    echo "  called from: $func(), $src, line $line"
}

set -o errtrace
trap 'trace_top_caller' ERR
Run Code Online (Sandbox Code Playgroud)

Cha*_*ffy 4

绝对——这正是错误陷阱的用途:

trap backtrace ERR
Run Code Online (Sandbox Code Playgroud)

在过去,我依稀记得发现有必要使之更像trap 'backtrace "${#BASH_SOURCE[@]}" "${BASH_SOURCE[@]}" "${#BASH_LINENO[@]}" "${BASH_LINENO[@]}"' ERR是解决错误(并从函数的 argv 中读取数组值);但是,我目前不记得该错误是什么以及它影响了哪些版本。