Bash& (&符号)运算符

时间:2012-02-13 09:46:13

标签: bash background-process exit-code

我正在尝试在bash shell中并行运行3个命令:

$ (first command) & (second command) & (third command) & wait

问题在于,如果first command失败,例如,退出代码为0(我猜是因为wait成功了。)

理想的行为是,如果其中一个命令失败,退出代码将为非零(理想情况下,其他正在运行的命令将被停止)。

我怎么能实现这个目标?

请注意,我想并行运行命令!

4 个答案:

答案 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"
}