Misha Moroshko
Misha Moroshko

Reputation: 171341

Bash & (ampersand) operator

I'm trying to run 3 commands in parallel in bash shell:

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

The problem with this is that if first command fails, for example, the exit code is 0 (I guess because wait succeeds).

The desired behavior is that if one of the commands fails, the exit code will be non-zero (and ideally, the other running commands will be stopped).

How could I achieve this?

Please note that I want to run the commands in parallel!

Upvotes: 21

Views: 38354

Answers (4)

Elifarley
Elifarley

Reputation: 1420

The shell function below will wait for all PIDs passed as arguments to finish, returning 0 if all PIDs executed without error.

The first PID that exists with an error will cause the PIDs that come after it to be killed, and the exit code that caused the error will be returned by the function.

wait_and_fail_on_first() {
  local piderr=0 i
  while test $# -gt 0; do {
    dpid="$1"; shift
    wait $dpid || { piderr=$?; kill $@; return $piderr ;}
  } done
}

Here's how to use it:

(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"
}

Upvotes: 0

potong
potong

Reputation: 58400

This might work for you:

parallel -j3 --halt 2 <list_of_commands.txt

This will run 3 commands in parallel.

If any running job fails it will kill the remaining running jobs and then stop, returning the exit code of the failing job.

Upvotes: 4

Karoly Horvath
Karoly Horvath

Reputation: 96258

the best I can think of is:

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

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

or

wait $p1 || ( kill $p2 $p3 && exit 1 )
...

however this still enforces an order for the check of processes, so if the third fails immediately you won't notice it until the first and second finishes.

Upvotes: 11

anubhava
anubhava

Reputation: 785126

You should use && instead of &. eg:

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

However this will NOT run your command in parallel as every subsequent command's execution will depend on exit code 0 of the previous command.

Upvotes: 2

Related Questions