gpt4 book ai didi

bash - trap/return 后退出状态到哪里去了?

转载 作者:行者123 更新时间:2023-11-29 09:05:55 25 4
gpt4 key购买 nike

由于 this question,我正在尝试在函数中使用 trap ,并提出了这个次要问题。给定以下代码:

d() {
trap 'return' ERR
false
echo hi
}

如果我运行 dtrap 会导致 shell 从函数返回而不打印“hi”。到目前为止,一切都很好。但是如果我第二次运行它,我会从 shell 中收到一条消息:

-bash: return: can only `return' from a function or sourced script

起初,我假设这意味着 ERR 信号发生了两次:一次是 false 给出非零退出状态(在函数内部),另一次是函数本身以非零退出状态返回(函数外)。但是这个假设并不支持这个测试:

e() {
trap 'echo +;return' ERR
false
echo hi
}

如果我运行上面的代码,无论我运行多少次,我都不会再收到来自 bash 的 can only return from a function or sourced script 警告。为什么 shell 对待复合命令不同于 trap arg 中的简单命令?

我的目标是维护导致函数退出的命令的实际退出状态,但我认为导致上述行为的任何原因也会使捕获退出状态变得复杂:

f() {
trap '
local s=$?
echo $s
return $s' ERR
false
echo hi
}

bash> f; echo $?
1
0

哇?有人可以解释为什么 $s 在这里扩展为两个不同的值,如果结果是同一个原因,则 returnecho + 之间的上述区别;返回?

最佳答案

您的第一个结论是正确的:ERR 信号发生了两次。

在第一次执行“d”期间,您全局定义了一个陷阱。这会影响下一个命令(当前对 d 的调用不受影响)。第二次执行'd'时,你又定义了一个trap(不是很有用),'false'的调用失败了,所以我们执行trap定义的handler。然后我们返回父 shell,其中 'd' 也失败了,所以我们再次执行陷阱。

只是一个评论。 ERR 可以作为 'sigspec' 参数给出,但 ERR 不是信号 ;-) 来自 BASH 手册:

If a sigspec is ERR, the command arg is executed whenever a sim‐
ple command has a non-zero exit status, subject to the following
conditions. [...]
These are the same conditions obeyed by the errexit option.

通过函数“e”,ERR 处理程序执行成功的“echo”命令。这就是为什么 'e' 函数不会失败,这就是为什么在这种情况下 ERR 处理程序没有被调用两次。

如果你尝试“e; echo $?”你会读到“0”。

然后我尝试了您的“f”函数。我观察到相同的行为(我很惊讶)。原因是不是“$s”的错误扩展。如果您尝试对一个值进行硬编码,您应该观察到在陷阱处理程序执行时忽略给“return”语句的参数。

我不知道这是正常行为还是 BASH 的错误...或者可能是避免解释器中无限循环的技巧:-)

顺便说一句,在我看来这不是一个很好的 trap 用法。我们可以通过创建子 shell 来避免陷阱的副作用。在这种情况下,我们避免了父 shell 中的错误,并保留了内部函数的退出代码:

g() (
trap 'return' ERR
false
echo hi
)

关于bash - trap/return 后退出状态到哪里去了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23809608/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com