tags:

views:

871

answers:

4

Wait is not waiting for all child processes to stop. This is my script:

#!/bin/bash

titlename=`echo "$@"|sed 's/\..\{3\}$//'`
screen -X title "$titlename"

/usr/lib/process.bash -verbose $@

wait

bash -c "mail.bash $@"
screen -X title "$titlename.Done"

I don't have access to /usr/lib/process.bash, but it is a script that changes frequently, so I would like to reference it... but in that script:

#!/bin/ksh
#lots of random stuff
/usr/lib/runall $path $auto $params > /dev/null 2>&1&

My problem is that runall creates a log file... and mail.bash is suppose to mail me that log file, but the wait isn't waiting for runall to finish, it seems to only be waiting for process.bash to finish. Is there anyway, without access to process.bash, or trying to keep my own up to date version of process.bash, to make the wait properly wait for runall to finish? (The log file overwrites the previous run, so I can't just check for the presence of the log file, since there is always one there)

Thanks, Dan

+3  A: 

wait only waits for direct children; if any children spawn their own children, it won't wait for them.

Ignacio Vazquez-Abrams
Is there anyway around this? If I want it to wait for all children, direct and indirect?
Dan
The only other way is to wait by PID or jobspec.
Ignacio Vazquez-Abrams
+1  A: 

The main problem is that because process.bash has exited the runall process will be orphaned and owned by init (PID 1). If you look at the process list runall won't have any visible connection to your process any more since the intermediate process.bash script exited. There's no way to use ps --ppid or anything similar to search for this "grandchild" process once it's orphaned.

You can wait on a specific PID. Do you know the PID of the runall process? If there's only one such process you could try this, which will wait for all running runalls:

wait `pidof runall`
John Kugelman
+5  A: 
(
    . /usr/lib/process.bash -verbose $@
    wait
)

Instead of letting the OS start process.bash, this creates a subshell, runs all the commands in process.bash as if they were entered into our shell script, and waits within that subshell.

There are some caveats to this, but it should work if you're not doing anything unusual.

ephemient
Dan
To have Ctrl-C kill the background process, use trap and kill: `pid=$!; trap "kill $pid; wait $pid; exit 0" SIGINT SIGTERM; wait $pid`
John Kugelman
+1  A: 

You could recuperate the PID of the process for whom you want to wait

And then pass this PID as an argument to the command Wait