Delay a Shell Script Safely with GNU sleep

A script that fires before its dependency is ready needs sleep to pause for a known interval, not a guess. You will check that the installed implementation accepts your arguments, and avoid confusing seconds with minutes, hours or days. Allow about five minutes. You need a shell and GNU coreutils; no elevated privileges are required.

1. Check the installed implementation

The examples target GNU sleep from coreutils 9.4. The package installed on this machine is coreutils 9.4-3ubuntu6.3. Start with read-only checks so you know which executable and version your shell will use:

$ command -v sleep
/usr/bin/sleep
$ sleep --version
sleep (GNU coreutils) 9.4

Do not use sudo for a normal delay. sleep waits in the current process and does not need to alter system files, services or permissions.

Checkpoint: If command -v sleep prints nothing, the command is not on your current PATH. Check the shell configuration or install the package through your normal system-management process before putting it in a script.

2. Pause for seconds

The simplest form is a number of seconds. The number may be fractional, so a short test does not need to wait for a whole second:

$ sleep 0.2
$ printf 'delay finished, exit status: %s\n' "$?"
delay finished, exit status: 0

The shell runs the next command only after sleep exits. A status of 0 means the delay completed normally, and the command prints no success message of its own, so a quiet terminal during the wait is expected.

In a script, keep the delay as its own command when the pause is part of the control flow:

#!/bin/sh
printf '%s\n' 'starting a short wait'
sleep 2
printf '%s\n' 'continuing after two seconds'

Use a comment or a descriptive variable when the reason matters, so a later reader doesn't mistake a required pause for an arbitrary slowdown.

3. Choose an explicit unit

The default unit is seconds. GNU sleep also accepts s for seconds, m for minutes, h for hours and d for days. An explicit suffix makes a script easier to review:

$ sleep 2s
$ sleep 5m
$ sleep 1h
$ sleep 0.5d

Warning: The last three commands above are examples of syntax, but the latter two really will wait for a long time. Do not paste them into an interactive shell unless that pause is intentional.

For a safe syntax check, use a small value with the suffix you are testing:

$ sleep 0.05m
$ printf 'minute-unit test passed\n'
minute-unit test passed
$ sleep 0.01h
$ printf 'hour-unit test passed\n'
hour-unit test passed

These values are converted to seconds by the command. They are not labels for a display and they do not change the system clock.

4. Add intervals instead of doing mental conversion

Two or more operands are accepted. GNU sleep waits for their sum, which is useful when a schedule is naturally expressed as separate pieces:

$ sleep 1s 0.2s
$ printf 'combined delay finished: %s\n' "$?"
combined delay finished: 0

Each operand can have its own suffix. The command treats 1m 30s as ninety seconds:

$ sleep 0.02m 0.05s
$ printf 'combined units finished: %s\n' "$?"
combined units finished: 0

For a configuration value supplied by another program, validate that the value is numeric before passing it to a shell command. Do not build an unquoted command string from untrusted input; prefer a fixed command and a separately quoted argument, for example:

$ DELAY='0.2s'
$ sleep "$DELAY"
$ printf 'requested delay completed: %s\n' "$?"
requested delay completed: 0

5. Put a delay into a retry loop

A common use is to wait between attempts. This example makes three attempts and stops after the first successful command. The placeholder command is deliberately harmless; replace it only with a command whose retry behaviour you understand:

#!/bin/sh
attempt=1
while [ "$attempt" -le 3 ]; do
    if /usr/bin/true; then
        printf 'attempt %s succeeded\n' "$attempt"
        break
    fi
    printf 'attempt %s failed, waiting before retry\n' "$attempt" >&2
    sleep 2
    attempt=$((attempt + 1))
done

Warning: Do not add a delay without a limit to a service or scheduled job. A failed dependency can otherwise leave a process sleeping and retrying forever. Keep the retry count, delay and failure policy visible near the loop.

6. Handle errors and cancellation

A missing operand or an invalid suffix is an error. Check the status when a delay is a required part of a larger script:

$ set +e
$ sleep 1x
sleep: invalid time interval '1x'
Try 'sleep --help' for more information.
$ printf 'exit status: %s\n' "$?"
exit status: 1
$ set -e

The exact quotation style in diagnostics can vary with the locale and shell, but a non-zero status is the useful signal. In a script running with set -e, an invalid delay can stop the script; handle it explicitly if that is not what you want.

An interactive wait can be interrupted with Ctrl-C. If the delay is running in the foreground, the shell returns to its prompt after the interrupt. Test interruption before relying on it as part of an operational recovery procedure. A background delay is a separate process and must be managed as such: record its process ID if you need to cancel it deliberately.

Done means