何时使用set -e

dim*_*mba 26 bash shell

set -e前段时间遇到过,我承认我喜欢它.现在,经过一段时间我回来写一些bash脚本.

我的问题是,是否有一些最佳实践何时使用set -e以及何时不使用它(例如小型/大型脚本等)或者我应该使用类似cmd || exit 1跟踪错误的模式?

and*_*otn 62

是的,你应该经常使用它.人们总是取笑Visual Basic,说它不是真正的编程语言,部分是因为它的"On Error Resume Next"声明.然而这是shell中的默认值!set -e应该是默认的.灾难的可能性太大了.


在命令失败的地方,您可以使用|| true或缩短形式||:,例如

grep Warning build.log ||:
Run Code Online (Sandbox Code Playgroud)

事实上,你应该更进一步,并有

set -eu
set -o pipefail
Run Code Online (Sandbox Code Playgroud)

在每个bash脚本的顶部.

-u使得它的错误引用一个不存在的环境变量,例如${HSOTNAME},在需要一些体操与检查的费用${#}你引用之前${1},${2}等.

pipefail使事情像misspeled-command | sed -e 's/^WARNING: //'引发错误.


Gre*_*ods 5

如果您的脚本代码在必要时仔细正确地检查错误,并以适当的方式处理它们,那么您可能永远不需要或不想使用set -e.

另一方面,如果您的脚本是一个一个接一个运行的简单命令顺序列表,并且如果您希望脚本在其中任何一个失败时终止,那么坚持set -e在顶部将正是您想要做的使您的脚本保持简单和整洁。一个完美的例子是,如果您正在创建一个脚本来编译一组源代码,并且您希望在遇到第一个有错误的文件后停止编译。

更复杂的脚本可以组合这些方法,因为您可以使用set +e它再次关闭其效果并返回到显式错误检查。

请注意,虽然set -e应该导致 shell 退出IFF,但任何未经测试的命令失败,当您的代码执行自己的错误处理时再次关闭它是明智的,因为很容易出现命令返回非零的奇怪情况您没有预料到的退出状态,甚至可能是您在测试中可能无法捕捉到的情况,以及脚本的突然致命终止会使某些内容处于不良状态。所以,不要使用set -e,或者在短暂使用后让它保持开启状态,除非你真的知道你想要它。

另请注意,您仍然可以定义一个错误处理程序,trap ERR以便set -e在生效时对错误条件执行某些操作,因为它仍将在 shell 退出之前运行。

  • 我不同意。我认为您应该默认使用“set -e”,并且只有在您确实需要时才将其删除。您最不想要的是一个未处理的错误,它会导致更多错误的级联或脚本中的某种不正确行为。 (5认同)
  • 超过 25 年的阅读和编写用于生产用途的脚本的经验表明 `set -e` 很少有用。 (2认同)