Bash&;(安培)运算符

Bash&;(安培)运算符,bash,background-process,exit-code,Bash,Background Process,Exit Code,我正在尝试在bash shell中并行运行3个命令: $ (first command) & (second command) & (third command) & wait 问题是,如果第一个命令失败,例如,退出代码是0(我猜是因为等待成功) 理想的行为是,如果其中一个命令失败,退出代码将为非零(理想情况下,其他正在运行的命令将停止) 我怎样才能做到这一点 请注意,我希望并行运行这些命令 您应该使用&而不是&。例如: first command &&

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

$ (first command) & (second command) & (third command) & wait
问题是,如果
第一个命令
失败,例如,退出代码是
0
(我猜是因为
等待
成功)

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

我怎样才能做到这一点


请注意,我希望并行运行这些命令

您应该使用
&
而不是
&
。例如:

first command && second command && third command && wait

但是,这不会并行运行您的命令,因为每个后续命令的执行将取决于上一个命令的退出代码0。

我能想到的最好方法是:

first & p1=$!
second & p2=$!
...

wait $p1 && wait $p2 && ..


但是,这仍然强制执行流程检查命令,因此,如果第三个流程立即失败,则在第一个和第二个流程完成之前,您不会注意到它。

这可能适用于您:

parallel -j3 --halt 2 <list_of_commands.txt

parallel-j3--halt 2下面的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"
}

我认为这在返回代码方面是可行的,但不会并行执行命令。我同意并在回答中做了说明。但是,如果命令并行运行,则无法检查退出代码,因为前一个命令在第二个命令运行时尚未退出。此处的主要约束是并行运行命令。我不介意用更复杂的bash脚本替换这一行,只要命令并行运行,并且在出现故障时退出代码将不为零。请理解,如果命令并行运行(或在后台运行),则无法立即获得退出状态,您必须等待命令退出。它将并行运行3个命令,但不满足OP.@MishaMoroshko google gnu parallel的退出代码要求@anubhava从《并行手册》
——暂停2立即终止所有作业,并在不进行清理的情况下退出。退出状态将是失败作业的退出状态。
(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"
}