在“trap EXIT”中获取Shell脚本的退出码

8
我希望我的Bash脚本可以有一个类似于这样的清理操作:

#! /bin/bash
set -eu
trap 'echo "E: failed with exitcode $?" 1>&2' ERR

true
false

使用$?似乎是一个自然的选择,但实际上并不是这样。它总是包含0。有没有办法在ERR陷阱中“窥视”退出代码?
【更新】我不知道我之前测试了什么。这段代码非常好用,所以我将其留在这里作为一个很好的例子。

我认为 $? 是正确的。你的脚本对我来说打印出了 1 - dogbane
1
哈哈,我明白哪里出问题了。当我测试这个功能时,我只写了一行代码并且引号使用错误。明确地说,“trap "echo exiting with $?" ERR”是不可行的,因为$?会在trap动作的定义处被求值。 - Roland Illig
对于任何正在搜索的人,这里有一个类似的问题 - JamesThomasMoon
1个回答

6
你的(可能是简化的)例子并没有展示你提到的问题:
+ set -eu
+ trap 'echo "E: failed with exitcode $?" 1>&2' ERR
+ true
+ false
++ echo 'E: failed with exitcode 1'
E: failed with exitcode 1

很有可能返回ERR 的命令是在&&或|| 下执行的,或者受到以下代码段中提到的其他条件的影响。引用自手册

如果sigspecERR,则每当简单命令具有非零退出状态时,将执行arg命令,但受以下条件的约束。如果失败的命令是紧随until 或 while 关键字之后的命令列表的一部分,则不会执行ERR 陷阱,也不会成为if 或elif 保留字后面的测试的一部分,也不会成为在&&或|| 列表中执行的命令,或者如果使用!反转命令的返回状态。这些是遵守errexit 选项的相同条件。

因此,如果您有以下内容:
#! /bin/bash
set -eu
trap 'echo "E: failed with exitcode $?" 1>&2' ERR

false && true

如果执行它,就不会触发失败的捕获:

+ set -eu
+ trap 'echo "E: failed with exitcode $?" 1>&2' ERR
+ false

这不就是errtrace选项可以解决的问题吗? - The Fool

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接