Sleeping and waiting on Linux

The Linux sleep and wait commands allow you to run commands at a chosen pace or capture and display the exit status of a task after waiting for it to finish. Sleep simply inserts a timed pause between commands. Wait, on the other hand, waits until a process completes before notifying you that it has finished.

Sleep

The sleep command pauses for a specified time. It’s generally used in a script, but works on the command line as well. In the example below, sleep pauses a minute between the two date commands.

$ date; sleep 60; date
Wed Sep 8 12:10:40 PM EDT 2021
Wed Sep 8 12:11:40 PM EDT 2021

The sleep command takes the numeric argument as the number of seconds. You can, however, ask it to sleep for various amounts of time by adding another character to the argument:
1m = 1 minute
2h = 2 hours
3d = 3 days
$ date; sleep 1m; date Wed Sep 8 12:16:38 PM EDT 2021 Wed Sep 8 12:17:38 PM EDT 2021

In fact, you can sleep for less than a second if you need.

.1 = 1/10th of a second
.01 = 1/100th of a second
.001 = 1/1,000th of a second
$ date; sleep .1; date
Wed Sep   8 12:18:57 PM EDT 2021
Wed Sep   8 12:18:57 PM EDT 2021

The sleep command is generally used to run a command periodically—once every 10 seconds or once a minute, for example—when you want to monitor some activity. For example, maybe you’re waiting for a coworker to log into a file server. You might run a command like this:

$ while true
> do
>     who
>     sleep 300
> done
shs      pts/0        2021-09-07 11:27 (192.168.0.10)
shs      pts/0        2021-09-07 11:32 (192.168.0.10)
shs      pts/0        2021-09-07 11:37 (192.168.0.10)
shs      pts/0        2021-09-07 11:42 (192.168.0.10)
shs      pts/0        2021-09-07 11:47 (192.168.0.10)
shs      pts/0        2021-09-07 11:52 (192.168.0.10)
nemo     pts/1        2021-09-07 11:52 (192.168.0.15)     <== finally!

You might want to watch the system for some kind of change. In the example below, we’re watching for changes in memory usage.

$ while true; do free; sleep 10; done
               total        used        free      shared  buff/cache   available
Mem:         6064768      767700     1482668        8136     3814400     4989360
Swap:        6064124           0     6064124
               total        used        free      shared  buff/cache   available
Mem:         6064768      767708     1482660        8136     3814400     4989352
Swap:        6064124           0     6064124

The point is that you don’t want the data to fly by your screen faster than you can read or make sense of it.

If you run a particular task once a day, you’re probably better off using cron, but you could do this with sleep. Just keep in mind that the task you’re running takes time too, so the task might not run at the same time every day.

Wait

The wait command captures the exit status of a backgrounded process after waiting for it to complete. The argument should be the process ID (PID) or job number of the process (e.g., 4563 or %2). You can try it out with a command like this (PID = 819227, job id = %1):

$ sleep 10 &
[1] 819227
$ wait %1
[1]+  Done                    sleep 10

You can also use it in a script like this. Replace the sleep command with the process that you want to wait for. This script also displays the exit status.

#!/bin/bash

sleep 5 &
process_id=$!
echo “PID: $process_id”
wait $process_id
echo “Exit status: $?”

The first line starts the sleep command in the background. The second grabs the process ID of the most recently executed backgrounded process ($!). The script then displays that information, waits for that process to finish and displays the exit status.

If you use wait -n (no additional arguments needed), wait will wait for any backgrounded task to complete. In the example below, the sleep 6 command would finish first, and the script would end, though the other two sleep processes would continue running in the background for some number of seconds.

#!/bin/bash

sleep 15 &
sleep 9 &
sleep 6 &
wait -n
echo “First job has been completed.”

If you ran the following script instead, it would tell you as each sleep process completes. Because of the timing, this would happen in the reverse order from when the sleep processes were started.

#!/bin/bash

sleep 15 &
sleep 9 &
sleep 6 &
wait -n
echo “First job has been completed.”
wait -n
echo “Next job has been completed.”
wait
echo “All jobs have been completed.”

NOTE: The process that is waited for must be a “child” (a process started within the current shell).

Wrap-Up

The sleep and wait commands can help when you want to observe system changes at a slower rate than they occur or get feedback from scripts as they complete various processes. Both can be used within scripts or on the command line. However, the wait command (a bash builtin) only works with processes run in the background.

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.
Related:

Copyright © 2021 IDG Communications, Inc.

SD-WAN buyers guide: Key questions to ask vendors (and yourself)