Read

Module 6 · Processes and jobs

sleep, time and measuring a command

Pause on purpose with sleep, measure how long a command takes with time, read real, user and sys correctly, and know the quirks of time when it is a program rather than a shell keyword.

What you will learn

  • Use `sleep` with fractions, suffixes and several arguments, and in polling loops.
  • Measure a command with `time` and interpret real, user and sys.
  • Capture the report with `2>`, `-o` or `-p`, and time pipelines through `sh -c`.

sleep: doing nothing, precisely

You have used sleep all through this module as a harmless process to look at. Its real job is to wait: a script that retries a download every ten seconds, a loop that polls until a file appears, a pause between two steps that must not overlap. sleep N waits N seconds and costs no CPU while it does; the kernel simply does not schedule it until the timer fires. BusyBox sleep accepts fractions (0.5), the suffixes s, m, h and d, and several arguments that are added together, so sleep 1m 30s waits ninety seconds. For really short pauses there is also usleep, which takes microseconds.

~% sleep 0.5
~% sleep 1m 30s &
~% ps -o args | grep '[s]leep 1m'
sleep 1m 30s
~% until [ -f /tmp/ready ]; do sleep 1; done; echo ready

time: how long did that take?

~% time sleep 2
real	0m 2.00s
user	0m 0.00s
sys	0m 0.00s
~% time wc -l /etc/passwd
9 /etc/passwd
real	0m 0.00s
user	0m 0.00s
sys	0m 0.00s

time CMD runs the command and, when it exits, reports three numbers. real is wall-clock time, what a stopwatch would show. user is CPU time spent running the program's own code, and sys is CPU time the kernel spent on its behalf (reading files, allocating memory). Comparing them is the useful part. sleep 2 shows real 2 and almost zero CPU: it was waiting, not working. A CPU-bound job shows real close to user plus sys. When real is much larger than user plus sys, the command spent its time waiting: for the disk, the network, a lock, or for the CPU itself because something with a better nice value was running (lesson 57).

Here, time is a program

In bash, time is a shell keyword that can time anything, pipelines and loops included. In this VM's ash it is the BusyBox applet /usr/bin/time (type time says so), an ordinary program that runs one other program. That has consequences. It cannot time builtins: time cd / fails with *can't execute 'cd'*. In time sort big | uniq -c, only sort is timed. The fix for both is to hand the whole thing to a shell: time sh -c 'sort big | uniq -c > /dev/null'. And the report is written to standard error, so time CMD > out.txt still prints it on the screen, while time CMD 2> t.txt captures it (along with any error messages of CMD).

~% time -p sleep 1
real 1.01
user 0.00
sys 0.00
~% time -p -o /tmp/t.txt sleep 1
~% cat /tmp/t.txt
real 1.01
user 0.00
sys 0.00
~% time -f '%e s' sleep 1
1.00 s
~% time cd /
time: can't execute 'cd': No such file or directory
OptionEffect
-pPOSIX format: real 1.01, plain seconds, easy to parse
-o FILEWrite the report to FILE instead of stderr
-aWith -o, append instead of overwrite
-f FMTCustom format: %e real, %U user, %S sys seconds
-vVerbose: memory, page faults, context switches…

Measuring by hand

~% start=$(date +%s); sleep 3; end=$(date +%s)
~% echo "took $((end - start)) s"
took 3 s

Inside a script you often want to time a whole section, not one command. Saving date +%s (seconds since 1970, lesson 68) before and after and subtracting is crude, whole seconds only, but works anywhere and is perfectly good for jobs that take minutes.

Commands in this lesson

CommandWhat it does
sleep 5 / sleep 0.5 / sleep 2mWait seconds, fractions, or with a suffix (s, m, h, d).
sleep 1m 30sArguments are added: 90 seconds.
time CMDRun CMD and report real, user and sys time on stderr.
time CMD 2> fileCapture the report in a file.
time -p -o file CMDPOSIX format, written straight to a file.
time sh -c 'a | b'Time a pipeline, loop or builtin.
date +%sSeconds since 1970; subtract two of them to time a section.

Quiz

  1. `time` reports real 10.2 s, user 0.1 s, sys 0.1 s. What was the command doing?

    • Computing hard
    • Mostly waiting: disk, network, a timer or the CPU queue
    • Running in the kernel
  2. After `time ls > out.txt`, where is the timing report?

    • At the end of out.txt
    • On the screen: time writes to standard error
    • Nowhere
  3. How long does `sleep 1m 30s` wait?

    • 1 minute
    • 90 seconds
    • It is an error
  4. Why does `time cd /tmp` fail in the lab VM?

    • /tmp does not exist
    • Here time is an external program and cd is a shell builtin it cannot execute
    • cd is too fast to measure
  5. Which option prints the report as `real 1.01` with plain seconds?

    • `-v`
    • `-p`
    • `-a`

Practice

  1. Time `sleep 2` and save the timing report (not the screen) into `/root/lab/l58/time.txt`.

  2. Time `wc -l /etc/passwd` in POSIX format and have `time` itself write the report to `/root/lab/l58/posix.txt`.

  3. Start in the background a `sleep` that lasts two hours, written with the `h` suffix.

Open this lesson in the app to do the tasks in a real Linux machine and have them checked.