Bash并行执行和退出码

5

我希望在bash脚本中并行运行多个命令,但如果任何一个命令失败(返回非零退出码),脚本的退出码必须是非零的。

我尝试使用sem (https://www.gnu.org/software/parallel/sem.html):

cat >script.sh <<EOF
sem -j+0 "sleep 2; echo 1"
sem -j+0 "sleep 4; exit 1; echo 2"
sem -j+0 "sleep 6; echo 3"
sem --wait
EOF
bash script.sh; echo $?

并将此进程后台运行:

cat >script.sh <<EOF
{sleep 2; echo 1} &
{sleep 4; exit 1; echo 2} &
{sleep 6; echo 3} &
wait
EOF
bash script.sh; echo $?

在这两种情况下,总体的退出码始终为0。

有什么想法吗?


1
你有没有考虑使用GNU parallel - Basile Starynkevitch
Sem是Parallel的包装器吗? - yellowhat
1
什么是“sem”?你有任何参考资料吗?请注意,你标记了“sem”,它代表着“搜索引擎营销”。Google Adwords是最常见的SEM方式之一。 - KamilCuk
2
这是wait命令的退出代码。从wait手册页中的“EXIT STATUS”部分可知:“0表示调用wait实用程序时没有操作数,并且由调用shell所知的所有进程ID都已终止。” - Dr Claw
2
sem 是一个符号链接到 GNU Parallel,使其像跨进程共享的信号量一样运行的工具。 - Mark Setchell
显示剩余4条评论
2个回答

4

但如果这些命令中的任何一个失败了(返回非零退出代码),则脚本的退出代码必须为非零。

那么编写这个条件。

childs=();
{ sleep 0.2; echo 1 ;} &
childs+=($!);
{ sleep 0.4; exit 1; echo 2; } &
childs+=($!);
{ sleep 0.6; echo 3; } &
childs+=($!);

ret=0;
for i in "${childs[@]}"; do
     if ! wait "$i"; then ret=1; fi
done
echo "ret=$ret"
exit "$ret"

2

感谢大家提供的答案。

根据Mark Setchell的建议,我认为对我来说最好的解决方案是:

#!/bin/bash
set -euo pipefail

cat <<EOF | parallel --halt 1
date; sleep 2; date; echo -e "1\n"
date; sleep 4; exit 1; date; echo -e "2\n"
date; sleep 6; date; echo -e "3\n"
EOF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接