背景

背景

背景

分别在bash 3、4、5中执行以下代码,会得到不同的结果。

(function handle_error () { echo ERROR; }; trap handle_error ERR; (exit 1))

想象一下(exit 1)您调用的命令可能会失败。在这种情况下它总是会失败,但这并不重要。您希望handle_error在它以非零退出代码退出时被调用。根据手册,这正是trap handle_error ERR应该做的。

问题

我有一个 bash 3 版本的本地系统,以及一个 bash 4 版本的完全不同操作系统的远程系统。

  • bash 3.2.57(1)、3.2.48(1):不返回任何输出。摘自man bash内置trap

    如果 sigspec 为 ERR,则只要简单命令具有非零退出状态,就会执行命令 arg,但需满足以下条件...

  • bash 4.4.23(1)、4.4.12(1):ERROR按预期打印。摘自man bash内置trap

    如果 sigspec 为 ERR,则只要管道(可能由单个简单命令组成)、列表或复合命令返回非零退出状态,就会执行命令 arg,但需满足以下条件...

  • bash 5.0.2(1):ERROR按预期打印。

该文档让我认为两个版本的行为应该相同,但事实并非如此。

我登录了#bashFreenode,并在那里验证了这种行为与所有主要版本 3、4 和 5 及其 shell 机器人 (nick) 的差异相同shbot,它允许您指定主要版本。这个 shell 机器人恰好在与我尝试过的两个系统不同的操作系统上运行,与我可以访问的 bash 的相同主要版本相比,它的次要版本不同。

问题

有人能指出一个权威来源来解释为什么这种行为在 bash 版本 3、4 和 5 中有所不同吗?我很难相信这是一个错误。一定还有另一个我想念的原因。

答案1

这看起来像是 Bash 3.2 中的一个错误。

我找不到条目变更日志这将直接匹配。仅含糊地提及更改errexit选项的行为以匹配 POSIX 共识(l从 bash-4.0-rc1 到 bash-4.0-release 的更改中的项目)。

这可能是相关的,因为 也有类似的问题errexit,这不会在 Bash 3.2 中触发它,但在 Bash 4.0 中会触发它(它应该不打印任何内容,因为当子 shell 命令失败时 shell 应该退出):

$ ./bash3.2 -c 'set -e; (exit 1); echo end.'
end.

请注意,这里的问题似乎是子 shell,因为这在两个版本中都有效:

$ ./bash3.2 -c 'trap "echo ERROR" ERR; false'
ERROR

相关内容