我有一个 shell 脚本(在 macOS 上运行 GNU bash,版本 3.2.57(1)-release),其中我 set -e
一开始,但我也想忽略一些潜在的失败,这样它们就不会结束脚本的执行。我通过附加 || ...
来做到这一点到相关命令:
#!/bin/sh
set -e
false || echo ignore failure
以上作品和输出ignore failure
,正如预期的那样。但是,如果我调用
false
命令通过 command
内置,此策略不起作用 - 脚本的以下版本会在 false
后立即退出失败,没有打印任何内容:#!/bin/sh
set -e
command false || echo ignore failure
这是为什么?即使在第二种情况下,我怎样才能获得忽略失败的期望行为?(在这个简化的例子中,我当然可以删除
command
内置函数,但在我的实际用例中,它是我无法控制的函数的一部分。)
最佳答案
为什么command false || echo
失败?
似乎这是 4.0 以下 bash 版本中的一个错误。
我下载了 old versions 3.2.57 和 4.0,在 Linux 上编译它们,然后运行你的脚本。我可以在 3.2.57 中重现您的问题。在 4.0 中,一切都按预期工作。
奇怪的是,我在 bash 的列表中找不到相应的注释 list of changes ,但如果您搜索 set -e
您会发现有关 set -e
行为的多个其他错误修正在其他版本中,例如:
This document details the changes between this version, bash-4.4-rc1, and the previous version, bash-4.4-beta.
[...]
o. Fixed a bug that caused set -e to be honored in cases of builtins invoking other builtins when it should be ignored.
如何解决问题?
最好的方法是使用更新版本的 bash。即使在 macOS 上,这也不是问题。您可以自己编译或从
brew
之类的东西安装它。 .除此之外,您可以使用解决方法,例如忽略
command
或者添加一个子shell ( command false; ) || echo ignore failure
(由 Nate Eldredge 提供)。在任何一种情况下,事情都会变得非常麻烦。由于您不知道错误发生的确切时间,因此您无法确定每次都正确地解决了它。
关于bash - 如何忽略通过命令内置调用的命令失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68143965/