我在bash脚本中使用堆栈回溯非常有用。然而,在我今天花时间制作一个最小的工作示例之前,总是存在我忽略的周期性故障:
#!/bin/bash # 1
set -o errexit # 2
set -o errtrace # 3
trap 'stacktrace' ERR # 4
function bad(){ # 5
return 1; } # 6
function good(){ bad; } # 7
function stacktrace(){ # 8
echo "Lines = ${BASH_LINENO[*]}" # 9
echo "Funcs = ${FUNCNAME[*]}" #10
} #11
function mymain(){ #12
good #13
} #14
echo "$BASH_VERSION" #15
mymain #16
# call tree:
#-------------
# mymain
# good
# bad
# return 1
#-------------------
# output is:
#-------------------
# 4.3.46(1)-release
# Lines = 6 13 16 0
# Funcs = stacktrace good mymain main
我有点希望在bad()返回错误代码时在第7行触发错误陷阱,但好吧,bash有很多方法。真正的问题是,我在这里看不到足够的信息来提供正确的堆栈追溯。函数good()中的第7行必定是此错误的堆栈追溯的一部分,无论你如何剪切它。
我可以想象一些非常讨厌的解决方法,但希望我能错过一些东西,有人可以指出如何在这种情况下正确识别第7行作为堆栈追踪的一部分。
我担心这是不幸的bash行为,它会在触发陷阱之前从堆栈中弹出bad(),但也会在将当前行#弹出到调用者之前(第7行),从而有效地结束报告该行#6属于good()而不是bad()。