如果特定命令失败,请不要中止脚本

时间:2018-04-05 11:53:20

标签: bash

我正在运行我的脚本:

#!/bin/bash -eu

根据需要,每当出现问题时都会中止脚本。但有时我希望其中一个命令最终失败,我想告诉bash忽略失败条件。在make中,您可以使用方便的方式忽略一个命令的状态:

-command

bash中有类似内容吗?想到的唯一一件事就是丑陋:

set +e
command
set -e

3 个答案:

答案 0 :(得分:9)

您可以在命令失败时执行无操作或将显式真实条件设置为

command || true

或no-op

command || :

这样做会强制命令列表(甚至是管道)在失败时返回退出状态0。参见

true | false
echo $?
1
true | false || true
echo $?
0
true | false || :
echo $?
0

答案 1 :(得分:5)

只需在命令前加!,以便在使用e运行脚本时退出状态不会退出脚本:

! command

What's the meaning of a ! before a command in the shell?所示,让! command否定给定命令的退出状态,并与set -e一起使用,防止shell退出该行的退出结果。

来自Bash Reference Manual → Pipelines

  

管道中的每个命令都在其自己的子shell中执行。管道的退出状态是管道中最后一个命令的退出状态(...)。 如果保留字'!'在管道之前,退出状态是退出状态的逻辑否定,如上所述。 shell在返回值之前等待管道中的所有命令终止。

然后我们获得有关4.3.1 The set Builtin的信息:

  

<强> -e

     

如果管道(请参阅管道)(可能包含单个简单命令(请参阅简单命令)),列表(请参阅列表)或复合命令(请参阅复合命令)返回非零状态,则立即退出。 如果失败的命令是紧跟在while或until关键字之后的命令列表的一部分,if语句中的部分测试,在&amp;&amp;中执行的任何命令的一部分,则shell不会退出 ;或||列表除了最后一个&amp;&amp;之后的命令或者||,管道中但是最后一个命令,或者,如果命令的返回状态被反转为!

一起,并引用我自己的答案:

  

当你有:

set -e
! command1
command2
     

您正在做的是绕过set -e中的command1标记。   为什么呢?

     
      
  • 如果command1正常运行,它将返回零状态。 !会否定它,但set -e不会因为它来而触发退出   如上所述,从与!相反的返回状态。
  •   
  • 如果command1失败,则会返回非零状态。 !将取消它,因此该行最终将返回零状态和   脚本将继续正常。
  •   

答案 2 :(得分:1)

不要认为有

可以通过

编写自己的功能
#!/bin/bash -eu

-(){
set +e
"$@"
set -e
}

- command

echo got here

可能希望使用函数名称,因为已在bash中使用-

正如chepner指出的那样,它只适用于简单的命令,而不是管道或列表。