【问题标题】:Execute multiple commands in a bash script sequentially and fail if at least one of them fails在 bash 脚本中按顺序执行多个命令,如果其中至少一个失败,则失败
【发布时间】:2013-04-11 10:27:39
【问题描述】:

我有一个 bash 脚本,用于按顺序执行多个命令,如果序列中至少有一个命令返回非零退出代码,我需要返回非零退出代码。我知道有一个wait 命令,但我不确定我是否理解如何使用它。

UPD 脚本如下所示:

#!/bin/bash
command1
command2
command3

所有命令都在前台运行。无论前一个命令返回哪种退出状态,所有命令都需要运行(因此它不能表现为“第一个错误时退出”)。基本上我需要收集所有的退出状态并相应地返回全局退出状态。

【问题讨论】:

标签: bash


【解决方案1】:

如果按顺序表示管道,则需要在脚本中设置pipefail,如set -o pipefail。来自man bash

管道的返回状态是最后一条命令的退出状态, 除非 pipefail 选项是 启用。如果启用 pipefail,则管道的返回状态是最后一个(最右边)的值 命令以非零状态退出,如果所有命令成功退出,则为零。如果保留 单词 !在管道之前,该管道的退出状态是退出的逻辑否定 状态如上所述。 shell 等待管道中的所有命令在之前终止 返回一个值。

如果您只是指顺序命令,那么只需检查每个命令的退出状态,如果退出状态不为零,则设置一个标志。让您的脚本返回标志的值,例如:

#!/bin/bash

EXIT=0
grep -q A <<< 'ABC' || EXIT=$?  # Will exit with 0
grep -q a <<< 'ABC' || EXIT=$?  # Will exit with 1
grep -q A <<< 'ABC' || EXIT=$?  # Will exit with 0
echo $EXIT                      # Will print 1
exit $EXIT                      # Exit status of script will be 1 

这使用逻辑运算符 OR || 仅在命令失败时设置 EXIT。如果多个命令失败,脚本将返回最后一个失败命令的退出状态。

如果这些命令不在后台运行,那么wait 与此处无关。

【讨论】:

    【解决方案2】:

    去做吧:

    EXIT_STATUS=0
    command1 || EXIT_STATUS=$?
    command2 || EXIT_STATUS=$?
    command3 || EXIT_STATUS=$?
    exit $EXIT_STATUS
    

    如果多个命令失败,不确定应该返回哪种状态。

    【讨论】:

    • 如果要在第一个错误后停止,可以使用“set -e”
    【解决方案3】:

    如果您想知道哪个命令失败,但不一定知道它的返回码,您可以使用:

    #!/bin/bash
    
    rc=0;
    counter=0;
    
    command1 || let "rc += 1 << $counter"; let counter+=1;
    command2 || let "rc += 1 << $counter"; let counter+=1;
    command3 || let "rc += 1 << $counter"; let counter+=1;
    
    exit $rc
    

    这使用 bash 中的位移来设置对应于哪个命令失败的位。

    因此,如果第一个命令失败,您将获得返回码 1 (=2^0),如果第三个命令失败,您将获得返回码 8 (=2^3),如果第一个和第三个命令失败,你会得到 9 作为返回码。

    【讨论】:

      【解决方案4】:

      如果您想知道哪个命令失败:

      #!/bin/bash
      EXITCODE_RESULT=0
      command1
      EXIT_CODE_1=$?
      command2
      EXIT_CODE_2=$?
      command3
      EXIT_CODE_3=$?
      
      for i in ${!EXIT_CODE_*}
      do
          # check if the values of the EXIT_CODE vars contain 1
          EXITCODE_RESULT=$(($EXITCODE_RESULT || ${!i}))
          if [ ${!i} -ne 0 ]
          then
              var_fail+="'$i' "
              
          else
              var_succ+="'$i' "
          fi
      done
      

      在 $var_fail 中你会得到一个失败的 EXIT_CODE 变量的列表,在 $var_succ 中你会得到一个成功的列表

      【讨论】:

        猜你喜欢
        • 2019-05-29
        • 1970-01-01
        • 1970-01-01
        • 2016-09-20
        • 2019-05-28
        • 2011-12-22
        • 2012-07-21
        • 2020-05-02
        • 1970-01-01
        相关资源
        最近更新 更多