You are here: Articles > Programming > Shell script

 See more articles about "Shell script "

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

 

Also see ...