从陷阱处理程序获取 bash 中的函数回溯(使用调用者)
我知道您可以使用“caller”来获取 bash 中函数调用的回溯:
#! /bin/bash
Backtrace () {
echo "Backtrace is:"
i=0
while caller $i
do
i=$((i+1))
done
}
myFunc () {
Backtrace
}
myFunc
打印:
Backtrace is:
11 myFunc ./test.sh
13 main ./test.sh
我的问题是,假设我有一个脚本,它使用“set -e”在任何未经检查的失败时终止。是否有可能获得脚本失败的行号(及其调用者)
我天真地尝试过:trap 'Backtrace' EXIT,但这给了我'1 main ./test.sh'而不是行号失败的命令
I know that you can use 'caller' to get a backtrace of function calls in bash:
#! /bin/bash
Backtrace () {
echo "Backtrace is:"
i=0
while caller $i
do
i=$((i+1))
done
}
myFunc () {
Backtrace
}
myFunc
Prints:
Backtrace is:
11 myFunc ./test.sh
13 main ./test.sh
My question is, lets say I have a script which uses 'set -e' to terminate on any unchecked failure. Is it possible to get a line number of where the script failed (and its callers)
I've tried naively doing: trap 'Backtrace' EXIT, but that gives me '1 main ./test.sh' rather than the line number of the failing command
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不确定它是否有效,但请尝试将
ERR
添加到您的trap
信号列表中。也许您的代码将在set -e
内容接管之前被调用,在这种情况下您将重新开始工作。I'm not sure if it will work, but try adding
ERR
to your list oftrap
'd signals. Maybe your code will be invoked before theset -e
stuff takes over, in which case you'll be back in business.如果陷阱是非零返回代码的结果,您可以通过捕获 SIGCHLD 并检查
$? 来确定这一点。 -eq 0
这样做的缺点是每当子进程返回时都会触发陷阱。但你可以用
[[ $? -eq 0 ]] return
有关详细信息,请参阅trap 无法捕获 SIGSEGV细节。
抱歉,如果我误解了您的问题,希望这对您有所帮助。我知道您的问题并非特定于 SIGSEGV,但它适用于任何时候
set -e
由于非零状态代码而导致退出,因此应该仍然适用编辑:为您节省悬念,要捕获 SIGCHLD,可以使用
trap; CHLD
,而不是trap <表达式> SIGCHLD
正如大多数理性人所认为的:)if the trap is a result of a non-zero return-code, you can figure this out by trapping SIGCHLD and checking if
$? -eq 0
The downside to this is that the trap will fire any time a child process returns. But you can just short-circuit with the
[[ $? -eq 0 ]] return
See trap fails to catch SIGSEGV for more detail.
Sorry if I misunderstood your question, hopefully this is helpful. I know your question is not specific to SIGSEGV, but it applies to any time
set -e
causes an exit due to a non-zero status code, so should still be applicableEDIT: To save you the suspense, to trap SIGCHLD, you use
trap <expression> CHLD
, nottrap <expression> SIGCHLD
as most reasonable people assume :)