12

I want to run some commands in parallel. When all of these commands are finished start the next one. I though the following approach will work

#!/bin/bash
command1 &
command2 &
command3 &&
command4

but it didn't. I need to run command4 when all the first three commands have been completely finished.

28
#!/bin/bash
command1 &
command2 &
command3 &

wait
command4

wait (without any arguments) will wait until all the backgrounded processes have exited.

The complete description of wait in the bash manual:

wait [-n] [n ...]

Wait for each specified child process and return its termination status. Each n may be a process ID or a job specification; if a job spec is given, all processes in that job's pipeline are waited for. If n is not given, all currently active child processes are waited for, and the return status is zero. If the -n option is supplied, wait waits for any job to terminate and returns its exit status. If n specifies a non-existent process or job, the return status is 127. Otherwise, the return status is the exit status of the last process or job waited for.

  • 1
    Another option is to save the PID of each child using something like PID1=$! and then wait for all of them with wait "$PID1" "$PID2" "$PID3". That is slightly more complicated, but will work if the process has other children which you do not want to wait for. – kasperd May 6 '17 at 20:37
  • 1
    @kasperd Better with a array in that case: cmd1 & pids=( $! ); cmd2 & pids+=( $! ); cmd3 & pids+=( $! ); wait "${pids[@]}" or something similar. – Kusalananda May 6 '17 at 21:29
  • @kasperd By "better" I mean "uses only one variable". Nothing inherently wrong with using many, and is probably totally ok for small cases like this. – Kusalananda May 6 '17 at 21:49
0

I like the wait answer, but just as an academic exercise, I think this would also work:

bash -c 'command1 & command2 & command3 &' && command4

Please correct me if I am wrong.

  • 2
    Did you test this? It absolutely does not work. Example: time bash -c "sleep 5 &sleep 5 &sleep 5 &" && echo foo If it doesn't say the bash command took five seconds, it didn't do what you want. – Seth Robertson May 6 '17 at 22:55
  • I tested it with sleep and echos and it seemed to work. Your example proves otherwise. – burger May 6 '17 at 23:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.