我正在运行我的脚本:
#!/bin/bash -eu
Run Code Online (Sandbox Code Playgroud)
如果出现问题,会在需要时中止脚本.但有时我希望其中一个命令最终失败,我想告诉bash忽略失败条件.在make你可以忽略一个命令与得心应手的状态:
-command
Run Code Online (Sandbox Code Playgroud)
有类似的东西bash吗?想到的唯一一件事就是丑陋:
set +e
command
set -e
Run Code Online (Sandbox Code Playgroud)
你可以在命令失败时做一个no-op或者设置一个明确的真实条件
command || true
Run Code Online (Sandbox Code Playgroud)
或者对于无操作
command || :
Run Code Online (Sandbox Code Playgroud)
这样做会强制命令列表(甚至是管道)在失败时返回退出状态0.看到
true | false
echo $?
1
true | false || true
echo $?
0
true | false || :
echo $?
0
Run Code Online (Sandbox Code Playgroud)
只需!在命令前添加a,以使其在使用以下命令运行时退出状态不会使脚本退出e:
! command
Run Code Online (Sandbox Code Playgroud)
正如在什么意思中看到的!在Shell中执行命令之前?,使! command否定给定命令的退出状态,并与一起使用set -e,可防止shell退出该行上的退出结果。
来自Bash参考手册?管道:
管道中的每个命令都在其自己的子Shell中执行。管道的退出状态是管道中最后一条命令的退出状态(...)。如果保留字为“!” 在管道之前,退出状态是如上所述退出状态的逻辑取反。在返回值之前,shell等待管道中的所有命令终止。
然后,我们获得有关4.3.1 The setBuiltin的信息:
-e
如果可能由单个简单命令(请参见简单命令),列表(请参见列表)或复合命令(请参见复合命令)组成的管道(请参见“管道”)返回非零状态,则立即退出。如果失败的命令紧随一段时间或直到关键字,if语句中的测试部分,&&或||中执行的任何命令的一部分之后,命令列表中的一部分,则外壳程序不会退出。列出除最后一个&&或||之后的命令,管道中除最后一个命令之外的任何命令,或者如果该命令的返回状态用!反转!。
一起,并引用我自己的答案:
当你有:
Run Code Online (Sandbox Code Playgroud)set -e ! command1 command2您正在做的是绕过。中的
set -e标志command1。为什么?
- 如果
command1运行正常,它将返回零状态。!会否定它,但set -e不会触发退出,因为如上所述,它来自返回状态,并以!取反。- 如果
command1失败,它将返回非零状态。!会将其取反,因此该行最终将返回零状态,并且脚本将正常继续。