我从 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 行属于好()而不是坏()。