我正在尝试在bash shell中并行运行3个命令:
$ (first command) & (second command) & (third command) & wait
问题在于,如果first command
失败,例如,退出代码为0
(我猜是因为wait
成功了。)
理想的行为是,如果其中一个命令失败,退出代码将为非零(理想情况下,其他正在运行的命令将被停止)。
我怎么能实现这个目标?
请注意,我想并行运行命令!
答案 0 :(得分:7)
first & p1=$!
second & p2=$!
...
wait $p1 && wait $p2 && ..
或
wait $p1 || ( kill $p2 $p3 && exit 1 )
...
然而,这仍然会强制执行检查流程的命令,因此如果第三个会立即失败,则在第一个和第二个完成之前您将不会注意到它。
答案 1 :(得分:4)
您应该使用&&
代替&
。例如:
first command && second command && third command && wait
然而,这不会并行运行您的命令,因为每个后续命令的执行将取决于前一个命令的退出代码0。
答案 2 :(得分:2)
这可能对您有用:
parallel -j3 --halt 2 <list_of_commands.txt
这将并行运行3个命令。
如果任何正在运行的作业失败,它将终止剩余的正在运行的作业,然后停止,返回失败作业的退出代码。
答案 3 :(得分:0)
下面的shell函数将等待所有作为参数传递的PID结束,如果所有PID执行无误,则返回0。
存在错误的第一个PID将导致其后的PID被终止,导致错误的退出代码将由该函数返回。
wait_and_fail_on_first() {
local piderr=0 i
while test $# -gt 0; do {
dpid="$1"; shift
wait $dpid || { piderr=$?; kill $@; return $piderr ;}
} done
}
这里是使用方法:
(first command) & pid1=$!
(second command) & pid2=$!
(third command) & pid3=$!
wait_and_fail_on_first $pid1 $pid2 $pid3 || {
echo "PID $dpid failed with code $?"
echo "Other PIDs were killed"
}