As others have said, there isn't any way to wait on "not" a process ID. However this pattern of code doesn't seem that bad to me, so I offer it as a suggested way of achieving what you're after.
It makes use of Bash arrays which you can then give as a list to the wait
command.
Example
A modified version of your example code, cmd.bash
.
!/bin/bash
array[0]=1
array[0]=2
sleep 30 &
pid=$!
pidArr=()
for i in ${array[@]}; do
for n in $(seq 3); do
if [ $n -eq 1 ]; then
sleep 31 > file &
pidArr+=($!)
else
sleep 32 >> file &
pidArr+=($!)
fi
done
done
echo ${pidArr[@]}
I've substituted sleep
commands in this example just to simulate some long running jobs that we can background. They have nothing to do with this other than to act as stand-ins.
Also the final echo
command is there purely so we can see what happens when the for loops complete. Ultimately we'll replace it with an actual wait
command, but let's not get ahead of ourselves.
Example run #1
So let's run our program and see what happens.
$ ./cmd.bash
24666 24667 24668
Now if we check ps
:
$ ps -eaf|grep sleep
saml 24664 1 0 22:28 pts/9 00:00:00 sleep 30
saml 24666 1 0 22:28 pts/9 00:00:00 sleep 31
saml 24667 1 0 22:28 pts/9 00:00:00 sleep 32
saml 24668 1 0 22:28 pts/9 00:00:00 sleep 32
If we wait a bit, these will ultimately finish. But this shows that if we add the process IDs to an array we can echo
them out afterwards.
Example #2
So let's change that echo
line out and swap in a wait
line now, something like this:
wait ${pidArr[@]}
Now when we run our modified version we see that it's waiting on ALL the process IDs:
$ ./cmd.bash
...after ~30 seconds passes
$
We get back our prompt. So we successfully waited for all the processes. A quick check of ps
:
$ ps -eaf|grep sleep
$
So it worked.
wait
also takes job id's as well as pid id's, which would be easier to get a list of compared to pid's (unless you store each PID in an array as you loop...) – Drav Sloan Sep 9 '13 at 0:00