user4833046
user4833046

Reputation:

WAIT for "1 of many process" to finish

Is there any built in feature in bash to wait for 1 out of many processes to finish? And then kill remaining processes?

pids=""
# Run five concurrent processes
for i in {1..5}; do
        ( longprocess ) &
        # store PID of process
        pids+=" $!"
done

if [ "one of them finished" ]; then
        kill_rest_of_them;
fi

I'm looking for "one of them finished" command. Is there any?

Upvotes: 8

Views: 5407

Answers (2)

chepner
chepner

Reputation: 532113

bash 4.3 added a -n flag to the built-in wait command, which causes the script to wait for the next child to complete. The -p option to jobs also means you don't need to store the list of pids, as long as there aren't any background jobs that you don't want to wait on.

# Run five concurrent processes
for i in {1..5}; do
    ( longprocess ) &
done

wait -n
kill $(jobs -p)

Note that if there is another background job other than the 5 long processes that completes first, wait -n will exit when it completes. That would also mean you would still want to save the list of process ids to kill, rather than killing whatever jobs -p returns.

Upvotes: 13

Andrew Henle
Andrew Henle

Reputation: 1

It's actually fairly easy:

#!/bin/bash
set -o monitor
killAll()
{
# code to kill all child processes
}

# call function to kill all children on SIGCHLD from the first one
trap killAll SIGCHLD

# start your child processes here

# now wait for them to finish
wait

You just have to be really careful in your script to use only bash built-in commands. You can't start any utilities that run as a separate process after you issue the trap command - any child process exiting will send SIGCHLD - and you can't tell where it came from.

Upvotes: 4

Related Questions