A simple script that waits for a process to complete and then executes a command

It is often necessary under unix/linux to wait for certain processes to complete before running other processes. At best this can cause needless delays and wasted time, while in the worst cases someone may actually forget to run some final processing.


The script we are going to create is a simple script that will loop while waiting for a process to complete, and then execute the commands provided in the argument. We’ll name our script waitforpid.sh and it will accept two arguments as follows:

PID = Process ID to watch
COMMAND = Commands to execute after the process completes

We’ll begin with some simple script setup, initialization, and parameter checking. As both of the parameters are required, we elected to keep the handling simple rather than going with something like xargs. We also added a delay variable to simplify the timing of the loop. This value is in seconds and you may change it to whatever value you like. For purposes of this script we left it to 5 seconds.


#!/bin/sh

#Grab the parameter off the command line
delay=5
pid=$1
cmd=$2
usage=0;

if [ "$pid" == "" ]
then
usage=1;
echo "PID is required"
fi

if [ "$cmd" == "" ]
then
usage=1;
echo "COMMAND is required"
fi

if [ "$usage" == "1" ]
then
echo "usage: waitforpid.sh PID COMMAND"
echo " where"
echo " PID = Process id to wait for"
echo " COMMAND = Command to be executed after it completes"
exit
fi

Now we get to the fun stuff, we’ll look for the process specified. On the first run, if the process doesn’t exist, we’ll simply exit with a message. This will help protect us in the event that the user miskeyed the PID.


#Redirect stdout and stderr of the ps command to /dev/null
ps -p$pid 2>&1 > /dev/null

#Grab the status of the ps command
status=$?

#A value of 0 means that it was found running
if [ "$status" == "0" ]
then
while [ "$status" == "0" ]
do
sleep $delay
ps -p$pid 2>&1 > /dev/null
status=$?
done

#The process has started, do something here
$cmd

#A value of non-0 means that it was NOT found running
else
echo Process with pid $pid is not running
fi

To test this script, we’ll use the sleep command as follows:

$ date; sleep 30 &
Thu Apr 12 16:35:38 CDT 2007
[1] 8388
$ ps -fp8388
UID PID PPID C STIME TTY TIME CMD
JoeUser 8388 16549 0 16:41 pts/0 00:00:00 sleep 30

As you can see, the number 8388 is the process id of our background process. Now we’ll start our script and tell it to look for that process id.


$ ./waitforpid.sh 8388 '/bin/date'
/bin/date
Thu Apr 12 16:36:11 CDT 2007
[1]+ Done sleep 30

As you can see, the script waited for the process to complete and then ran the date command that we specified. I’ve included the full script below so that you don’t have to put the pieces back together.

delay=5
pid=$1
cmd=$2
usage=0;

if [ "$pid" == "" ]
then
usage=1;
echo "PID is required"
fi

if [ "$cmd" == "" ]
then
usage=1;
echo "COMMAND is required"
fi

if [ "$usage" == "1" ]
then
echo "usage: waitforpid.sh PID COMMAND"
echo " where"
echo " PID = Process id to wait for"
echo " COMMAND = Command to be executed after it completes"
exit
fi

#Redirect stdout and stderr of the ps command to /dev/null
ps -p$pid 2>&1 > /dev/null

#Grab the status of the ps command
status=$?

#A value of 0 means that it was found running
if [ "$status" == "0" ]
then
while [ "$status" == "0" ]
do
sleep $delay
ps -p$pid 2>&1 > /dev/null
status=$?
done

#The process has started, do something here
echo $cmd
$cmd

#A value of non-0 means that it was NOT found running
else
echo Process with pid $pid is not running
fi

The Conversation

Follow the reactions below and share your own thoughts.

  • David

    This is very intriguing, but I wonder why you didn’t use the wait command?

    $ date ; sleep 30 &
    Sat Nov 29 12:53:58 CST 2008
    [1] 7695
    $ wait %1
    $

    Simple.

  • Parvathi

    Very helpful… and very clear.
    Thanks for the script…

  • Anonymous

    What if I have process name only and didn’t know process ID??

  • Nick

    @David,

    wait only works for processes spawned by the current shell.

    build_helper.sh: line 6: wait: pid 32015 is not a child of this shell

    This script seems very helpful e.g. when using “service stop” and waiting for its pid to exit as indicated by a pidfile from /var/local/run/.pid.

    Nick