按顺序在bash脚本中执行多个命令,如果至少其中一个命令失败,则会失败

时间:2013-04-18 10:39:19

标签: bash

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

UPD 脚本如下所示:

#!/bin/bash
command1
command2
command3

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

4 个答案:

答案 0 :(得分:41)

就这样做:

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

如果有几个命令失败,不确定它应返回哪种状态。

答案 1 :(得分:8)

如果按顺序表示管道,则需要在脚本中设置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 :(得分:4)

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

#!/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作为返回码。

答案 3 :(得分:0)

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

#!/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中,将获得成功的变量的列表