Linux.com

Everything Linux and Open Source

CLI Magic: Wait or sleep?

March 28, 2005 (9:00:00 AM)  -  4 years, 8 months ago

By:

Usually, you want a shell script to just run to completion, one command after another. There are times, however, when a sequence of events includes a step upon which subsequent steps depend for successful execution. For these times, two useful commands are wait and sleep, both of which cause a delay in the script execution. Updated code samples
The wait command man page simply states that it pauses script execution until a specified process ID completes. The man page for the sleep command is a single line stating that it causes a script to pause for specified period of time.

How do you decide which is appropriate for the script at hand? In some cases it won't make any difference to the successful completion of the script. Other times it can be the difference between success and total failure to produce the expected results.

As an example of a script in which the difference is potentially significant, let's use a root cron script that runs every day to update a database of file locations. (Please note that this is an example only, not something I have debugged and actually run.)

  #! /bin/sh 
cd /stuff/flix 
ftp <*.mpg files from a source> 
updatedb 
locate mpg |grep /stuff/flix 
exit 0

While this would appear to be a valid construction, it will fail if executed, because the line beginning with locate would be called before the previous line had run to completion. On a large system the updatedb process can take several minutes. This is the perfect time to use the wait command.

  #! /bin/sh 
cd /stuff/flix 
sftp <*.mpg files from a source> &
wait 
updatedb &
wait 
locate mpg |grep /stuff/flix 
exit 0 

A call to wait after the sftp command delays the script until all file transfer activity has completed. Similarly, inserting wait after the updatedb call delays further processing until the updatedb process finishes.

Why not use the sleep command instead? In the above illustration, having the script delay for only a specified amount of time would work only if the amount of time specified was sufficiently long for the task to complete. You would have to guess how much time would be required for the longest transfer of files. Since that time can vary significantly due to many factors, even if the file size(s) are exactly the same every day, the use of wait insures that the process has completed.

So when is the sleep command the right choice? Let's look at another example, this time snipped from the /etc/init.d/smb script, to illustrate the choice. Please note: these code samples are for illustration only!

# wait for cupsd to be ready 
function wait_for_cupsd 
{ 
        echo -n "Samba SMB: Waiting for cupsd to get ready" 
        SAMBA_CUPSD_TIMEOUT=30 
        rc_timer_on ${SAMBA_CUPSD_TIMEOUT} 42 
        START=$( date +%s) 
        while [ $(( $( date +%s) - ${START} )) -lt ${SAMBA_CUPSD_TIMEOUT} ]; 
do 
                lpstat -r &>/dev/null 
                LPSTAT_RC=$? 
                if [ ${LPSTAT_RC} -eq 0 ]; then break 
                else sleep 2 
                fi 
        done 
        rc_timer_off 

        test ${LPSTAT_RC} -eq 0 && rc_status -v || rc_status -s 
        rc_reset 
} 

This script calls the sleep command within a while/do/done loop with a parameter of two seconds as the else branch of an if/then/else test. This causes the loop to re-execute every two seconds until the printer daemon is ready to accept print jobs. Here we know exactly how long we wish to wait before testing the status again.

That's the real difference in making the choice between wait and sleep -- knowing the amount of time to delay the script.

Now, armed with the knowledge of what the wait and sleep commands can do, and how to decide which to use, we come to the fun part of script usage -- finding applications for what we have learned that can make the computing experience more productive or just less hassle. Any multi-step computing task that you perform frequently is a good candidate for becoming a script.

A cron tip

Because I mentioned the use of a cron job earlier, here's a little comment header that can make life a lot easier when setting your crontab. I use a file called cronset that I can edit easily. I then call crontab passing it cronset as a command-line parameter.

 
MAILTO="" 
#################################################################### 
#minute (0-59),                                                    # 
#|      hour (0-23),                                               # 
#|      |       day of the month (1-31),                           # 
#|      |       |       month of the year (1-12),                  # 
#|      |       |       |       day of the week (0-6 with 0=Sunday)# 
#|      |       |       |       |       commands                   # 
#################################################################### 
30      01      *       *       *       /home/jim/bin/cleartmp 

Jim Westbrook has been BBS sysop for seventeen years, a network admin since 1983, and a Linux user and advocate since 1999. He is the current president of the Austin Linux Group, in Austin, Texas.

Read in the original layout at: http://www.linux.com/archive/articles/113976