bash:访问陷阱函数中的函数调用堆栈

bash:访问陷阱函数中的函数调用堆栈

处理 bash 函数调用堆栈跟踪...

脚本捕获错误并运行callStack()函数。但在捕获时,它总是显示函数本身的调用堆栈callStack(),而不是发生捕获的函数,如...

/share/sbin/zimdialog: line 647: status: command not found
    Function call stack ( command.function() ) ...
      /share/sbin/zimdialog.main()
        /share/sbin/include.callStack()

希望获得包含errantFunction()类似内容的堆栈跟踪......

/share/sbin/zimdialog: line 647: status: command not found
    Function call stack ( command.function() ) ...
      /share/sbin/zimdialog.main()
        /share/sbin/zimdialog.errantFunction()
          /share/sbin/include.callStack()

该陷阱的编码为...

trap callStack HUP INT QUIT TERM ERR

callStack()函数的编码为...

function callStack () {
  { isNotNull "$1" && isHelp "$1"; } && {
    helpShow 'callStack
    Diagnostics regarding where the call to this function came from'
    return
  }
  local T="${T}  "
  local STACK=
  i=${#FUNCNAME[@]}
  ((--i))
  printf "${T}Function call stack ( command.function() ) ...\n" >&2
  T="${T}  "
  while (( $i >= 0 ))
  do
    STACK+="${T}${BASH_SOURCE[$i]}.${FUNCNAME[$i]}()\n"
    T="${T}  "
    ((--i))
  done
  printf "$STACK" >&2
}

补充:set -E等不起作用

/share/sbin/gshlib...

set -e
set -E
set -T
shopt -s extdebug

trap $(callStack) ERR

function initialize () {
    :
  logstatus                         #<<< ERROR FOR TESTING trap
}
export -f initialize

错误地命名为logStatusSpring ,我得到的最好的是...... logstatus/share/sbin/gshlib.initialize()trap ERR

    Function call stack ...
    | /share/sbin/archive.main()
    |   /share/sbin/include.include()
    |     /share/sbin/gshlib.source()
    |       /share/sbin/include.callStack()
/share/sbin/gshlib: line 109: logstatus: command not found

我想要得到的是...

    Function call stack ...
    | /share/sbin/archive.main()
    |   /share/sbin/include.include()
    |     /share/sbin/gshlib.source()
    |       /share/sbin/gshlib.initialize()
    |         /share/sbin/include.callStack()
/share/sbin/gshlib: line 109: logstatus: command not found

答案1

您需要set -E(或set -o errtrace) 以便trap ERR被调用的函数继承。

一旦执行此操作,您可能会发现会收到级联错误报告,因为调用堆栈中的每个函数都将被脚本错误终止(使用非零退出代码)。

ERR在失败不被视为致命的上下文中(例如ifwhile),不会通过调用 shell 函数来触发。在这样的上下文中,堆栈跟踪可能不会出现,尽管我不确定它是如何特定于版本的。

相关内容