[英]How do I execute multiple commands in parallel on an array of parameters with bash, and fail if at least one of them failed
[英]Execute multiple commands in a bash script sequentially and fail if at least one of them fails
我有一个 bash 脚本,用于按顺序执行多个命令,如果序列中至少有一个命令返回非零退出代码,我需要返回非零退出代码。 我知道有一个wait
命令,但我不确定我是否理解如何使用它。
UPD脚本如下所示:
#!/bin/bash
command1
command2
command3
所有命令都在前台运行。 无论前一个命令返回哪种退出状态,所有命令都需要运行(因此它不能表现为“出现第一个错误时退出”)。 基本上我需要收集所有退出状态并相应地返回全局退出状态。
去做就对了:
EXIT_STATUS=0
command1 || EXIT_STATUS=$?
command2 || EXIT_STATUS=$?
command3 || EXIT_STATUS=$?
exit $EXIT_STATUS
如果几个命令失败,不确定它应该返回哪个状态。
如果按顺序您的意思是管道,那么您需要在脚本中设置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
在这里无关紧要。
如果您想知道哪个命令失败了,但不一定是它的返回码,您可以使用:
#!/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 作为返回码。
如果您想知道哪个命令失败了:
#!/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 中一个成功的列表
EXIT_STATUS=0
command1 || EXIT_STATUS=$? && echo "command1 failed with $EXIT_STATUS"
command2 || EXIT_STATUS=$? && echo "command2 failed with $EXIT_STATUS"
command3 || EXIT_STATUS=$? && echo "command3 failed with $EXIT_STATUS"
exit $EXIT_STATUS
鉴于您只能返回一种退出状态,最好记录哪一种退出状态。
此处EXIT_STATUS
仅在command1
、 command2
、 command3
任何一个失败时才被分配一个非零值,并且我们在每次失败时都进行记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.