获取存储在别名中的源文件的名称

时间:2015-02-03 20:07:41

标签: bash error-handling bash-trap

我正在尝试将一些错误检查添加到我的bashrc库中。它们是模块化的,并在for循环中加载:

for rcfile in $BASHRCD/*.bash; do
  source "$rcfile"
done

我使用一个标志来启用调试(如果我正在尝试解决问题)。我已经以不同的方式重写了以下函数许多,但是无论如何都没有找到发生错误的 sourced 脚本的名称。我已经尝试禁用pipefail,我已经尝试解析$ rcfile的值,我试图捕获并明确地将参数传递给陷阱等等。我故意没有设置errexit,因为我没有当我有错误时希望我的shell退出 - 我只想要有意义的输出。 :)这就是我现在拥有的:

if [[ ${DEBUG:-0} -eq 1 ]]; then

  shopt -s extdebug
  set -o errtrace
  set -o nounset
  set -o pipefail

  _err_handler() {
    local _ec="$?"
    local _cmd="${BASH_COMMAND:-unknown}"
    traceback 1
    _showed_traceback=t
    echo "The command ${_cmd} exited with exit code ${_ec}." 1>&2
  }

  traceback () {
    # Hide the traceback() call.
    local -i start=$(( ${1:-0} + 1 ))
    local -i end=${#BASH_SOURCE[@]}
    local -i i=0
    local -i j=0

    echo "Traceback (last called is first):" 1>&2
    for ((i=${start}; i < ${end}; i++)); do
      j=$(( $i - 1 ))
      local function="${FUNCNAME[$i]}"
      local file="${BASH_SOURCE[$i]}"
      local line="${BASH_LINENO[$j]}"
      echo "     ${function}() in ${file}:${line}" 1>&2
    done
  }

fi

trap _err_handler ERR

当我尝试加载包含错误的文件时,它会生成如下输出:

/Users/nfarrar/.bashrc
Traceback (last called is first):
  source() in /Users/nfarrar/.bashrc:43
  source() in /Users/nfarrar/.bash_profile:94
The command source "$rcfile" exited with exit code 1.
bash: SOMEFILE: unbound variable

引用的bashrc行是for循环中的行(如上所示)源$ rcfile。回溯引用了我的.bash_profile,因为.bashrc来自它。这很有用,但我真正想要的是发生错误的源文件中的文件名和行号。

修改
此代码段显示BASH_SOURCE数组的输出并遍历调用程序堆栈。

_err_trap() {
  echo "Number of items in BASH_SOURCE: ${#BASH_SOURCE[@]}"
  echo "${BASH_SOURCE[@]}"

  i=0;
  while caller $i; do
    ((i++))
  done
}
trap _err_trap ERR

它会产生以下输出,表明无法获取源的脚本不在BASH_SOURCE或调用者帧中:

Number of items in BASH_SOURCE: 3
/Users/nfarrar/.bash/lib/debug.bash /Users/nfarrar/.bashrc /Users/nfarrar/.bash_profile
43 source /Users/nfarrar/.bashrc
94 source /Users/nfarrar/.bash_profile

列出的三个项目是:

  1. .bash / lib / debug.bash(这是来源并包含_err_handler&amp; traceback)
  2. .bashrc(由.bash_profile提供并运行获取目录中所有文件的循环)
  3. .bash_profile,来源.bashrc

0 个答案:

没有答案