What Does timeout Do For You?
The timeout command allows you to set a limit on the length of time a program will run for. But why would you want to do that?
One case is when you know exactly how long you want a process to run for. A common use-case is to have timeout control a logging or data-capture program so that the log files don’t relentlessly devour your hard drive space.
Another case is when you don’t know how long you want a process to run for, but you do know you don’t want it to run indefinitely. You might have a habit of setting processes running, minimizing the terminal window, and forgetting about them.
Some programs–even simple utilities—can generate network traffic at levels that can impede the performance of your network. Or they can tie up the resources on a target device, slowing down its performance. (ping, I’m looking at you.) Leaving these types of programs running for extended periods while you’re away from your computer is bad practice.
timeout is part of the GNU Core Utils so Linux and Unix-like operating systems such as macOS all have timeout built right in. There’s nothing to install; you can use it right out of the box.
Getting Started With timeout
Here’s a simple example. For example, with its default command-line options, the ping command will run until you stop it by hitting Ctrl+C. If you don’t interrupt it, it’ll just keep going.
By using timeout, we can make sure ping doesn’t run on and on, chewing up network bandwidth and pestering whatever device is being pinged.
This next command uses timeout to time-limit ping. We’re allowing 15 seconds of run time for ping.
After 15 seconds timeout terminates the ping session and we are returned to the command line prompt.
Using timeout With Other Time Units
Note that we didn’t have to add an “s” behind the 15. timeout assumes the value is in seconds. You could add an “s,” but it really makes no difference.
To use a time value measured in minutes, hours or days add an “m,” an “h,” or a “d.”
To have ping run for three minutes, use the following command:
ping will run for three minutes before timeout steps in and halts the ping session.
Limiting Data Capture With timeout
Some data capture files can grow big very quickly. To prevent such files becoming unwieldy or even problematic in size, limit the amount of time the capture program is allowed to run.
In this example, we’re using tcpdump, a network traffic capture tool. On the test machines that this article was researched on, tcpdump was already installed in Ubuntu Linux and Fedora Linux. It had to be installed on Manjaro Linux and Arch Linux, with the following command:
We can run tcpdump for 10 seconds with its default options, and redirect its output to a file called capture.txt with the following command:
(tcpdump has its own options to save captured network traffic to a file. This is a quick hack because we’re discussing timeout, not tcpdump.)
tcpdump starts capturing network traffic and we wait for 10 seconds. And 10 seconds comes and goes and tcpdump is still running, and capture.txt is still growing in size. It’s going to take a hasty Ctrl+C to halt tcpdump.
Checking the size of capture.txt with ls shows that it grew to 209K in a matter of seconds. That file was growing fast!
What happened? Why didn’t timeout stop tcpdump?
It’s all to do with signals.
Sending The Right Signal
When timeout wants to stop a program it sends the SIGTERM signal. This politely asks the program to terminate. Some programs may choose to ignore the SIGTERM signal. When that happens, we need to tell timeout to be a little more forceful.
We can do that by asking timeout to send the SIGKILL signal instead.
The SIGKILL signal cannot be “caught, blocked or ignored”—it always gets through. SIGKILL doesn’t politely ask the program to stop. SIGKILL hides around the corner with a stopwatch and a cosh.
We can use the -s (signal) option to tell timeout to send the SIGKILL signal.
This time, as soon as 10 seconds have elapsed, tcpdump is stopped.
Asking Politely First
We can ask timeout to try to stop the program using SIGTERM, and to only send in SIGKILL if SIGTERM didn’t work.
To do this, we use the -k (kill after) option. The -k option requires a time value as a parameter.
In this command, we’re asking timeout to let dmesg run for 30 seconds, and to then terminate it with the SIGTERM signal. If dmesg is still running after 40 seconds, it means the diplomatic SIGTERM was ignored and timeout should send in SIGKILL to finish the job.
dmesg is a utility that can monitor the kernel ring buffer messages and display them in a terminal window.
dmesg runs for 30 seconds and stops when it receives the SIGTERM signal.
We know it wasn’t SIGKILL that stopped dmesg because SIGKILL always leaves a one-word obituary in the terminal window: “Killed.” That didn’t happen in this case.
Retrieving the Program’s Exit Code
Well-behaved programs pass a value back to the shell when they terminate. This is known as an exit code. Typically this is used to tell the shell–or whatever process launched the program— whether problems were encountered by the program as it ran.
timeout provides its own exit code, but we may not care about that. We are probably more interested in the exit code from the process that timeout is controlling.
This command lets ping run for five seconds. It is pinging a computer called Nostromo, which is on the test network that was used to research this article.
The command runs for five seconds and timeout terminates it. We can then check the exit code using this command:
The exit code is 124. This is the value timeout uses to indicate the program was terminated using SIGTERM. If SIGKILL terminates the program, the exit code is 137.
If we interrupt the program with Ctrl+C the exit code from timeout is zero.
If the execution of the program ends before timeout terminates it, timeout can pass the exit code from the program back to the shell.
For this to happen the program must come to a halt of its own accord (in other words, it is not terminated by timeout), and we must use the –preserve-status option.
If we use the -c (count) option with a value of five ping will only fire off five requests. If we give timeout a duration of one minute, ping will have definitely terminated by itself. We can then check the exit value using echo.
ping completes its five ping requests and terminates. The exit code is zero.
To verify the exit code is coming from ping, let’s force ping to generate a different exit code. If we try to send ping requests to a non-existent IP address, ping will fail with an error exit code. We can then use echo to check that the exit code is non-zero.
The ping command obviously cannot reach the non-existent device, so it reports the error and closes down. The exit code is two. This is the exit code ping uses for general errors.
Setting Ground Rules
timeout is all about providing some boundaries to running programs. If there’s a danger the log files might overrun your hard drive or that you might forget you left a network tool running, wrap them in timeout and let your computer self-regulate.