How do I wait on a program started in another shell
I Definitely prefer the EDIT #3 solution (see bellow).
if its not in the same shell use a while loop with condition on ps -p returning true. Put a sleep in the loop to reduce processor usage.
while ps -p <pid> >/dev/null 2>&1
do
sleep 10
done
or if your UNIX is supporting /proc (for instance HP-UX still does not).
while [[ -d /proc/<pid> ]]
do
sleep 10
done
If you want a timeout
timeout=6 # timeout after 1mn
while ((timeout > 0)) && ps -p <pid> >/dev/null 2>&1
do
sleep 10
((timeout -= 1))
done
EDIT #1
There is an other way : don't use cron. Use the batch command to stack your jobs.
For instance you could daily stacks all your jobs. Batch can be tuned to allow some parallelism so a blocked job will not stops the all stack (It depends on the operating system).
EDIT #2
Create a fifo in your home directory:
$ mkfifo ~/tata
at the end of your job:
echo "it's done" > ~/tata
at the start of the other job (the one who is waiting):
cat ~/tata
It's not polling it is old good blocking IO.
EDIT #3
Using signals:
At the begin of the script(s) who is(are) waiting :
echo $$ >>~/WeAreStopped
kill -STOP $$
at the end of your long job :
if [[ -f ~/WeAreStopped ]] ; then
xargs kill -CONT < ~/WeAreStopped
rm ~/WeAreStopped
fi
You can modify your cron job to use some flag.
Instead of
2 2 * * * /path/my_binary
You can use
2 2 * * * touch /tmp/i_m_running; /path/my_binary; rm /tmp/i_m_running
And just monitor this file in script or even manually. If it exists, then your program is running; otherwise feel free to do whatever you want.
The script sample:
while [[ -f /tmp/i_m_running ]] ; do
sleep 10 ;
done
launch_whatever_you_want
In case you don't like to use sleep
, you can modify the script and run it via cron once per X minutes.
In that case script sample will be:
[[ -f /tmp/i_m_running ]] && { echo "Too early" ; exit ; }
launch_whatever_you_want
This way is a little bit easier, as you don't have to find the PID of your cron process.
There's no facility for a process to wait for another process to finish, except for a parent to wait for one of its child processes to finish. If you can, launch the program through a script:
do_large_amount_of_work
start_interactive_program
If you can't do that, for example before you want to start the large amount of work from a cron job but the interactive program from the context of your session, then make this
do_large_amount_of_work
notify_completion
There are several ways to implement notify_completion
. Some desktop environments provide a notification mechanism (Open a window on a remote X display (why "Cannot open display")? may be useful). You can also make one using file change notifications. On Linux, the file change notification facility is inotify.
do_large_amount_of_work
echo $? >/path/to/finished.stamp
To react to the creation of /path/to/finished.stamp
:
inotifywait -e close_write -q /path/to/finished.stamp
start_interactive_program
If you can't change the way do_large_amount_of_work
is invoked, but you know what file it modifies last, you can use the same mechanism to react when that file is closed. You can also react to other events such as the renaming of a file (see the inotifywait
manual for a list of possibilities).