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).