从陷阱处理程序获取 bash 中的函数回溯(使用调用者)

发布于 2024-11-03 13:54:18 字数 444 浏览 3 评论 0原文

我知道您可以使用“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

简单气质女生网名 2024-11-10 13:54:18

我不确定它是否有效,但请尝试将 ERR 添加到您的 trap 信号列表中。也许您的代码将在 set -e 内容接管之前被调用,在这种情况下您将重新开始工作。

I'm not sure if it will work, but try adding ERR to your list of trap'd signals. Maybe your code will be invoked before the set -e stuff takes over, in which case you'll be back in business.

你是年少的欢喜 2024-11-10 13:54:18

如果陷阱是非零返回代码的结果,您可以通过捕获 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 applicable

EDIT: To save you the suspense, to trap SIGCHLD, you use trap <expression> CHLD, not trap <expression> SIGCHLD as most reasonable people assume :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文