When executing scripts or commands in a Linux terminal, it is a common requirement to set an absolute time limit on how long a process is allowed to run. For example, if you run a daily network ping test that occasionally hangs indefinitely due to routing issues, or if you execute a database backup script that should take no longer than five minutes, you do not want these stalled processes consuming system resources forever. The Linux timeout command is a simple, built-in utility that runs any given command and automatically kills it if it fails to complete within a specified duration.
Understanding the Syntax
The timeout command acts as a wrapper around the command you actually want to execute. The basic syntax is:
timeout [DURATION] [COMMAND]
By default, if you specify a number without a unit, timeout assumes you mean seconds. However, you can use suffixes to specify different time units:
- s for seconds (the default)
- m for minutes
- h for hours
- d for days
For example, to run a network ping command but force it to terminate after exactly 10 seconds, you would write:
timeout 10s ping 8.8.8.8
How the Timeout Command Kills Processes
When the specified duration expires, the timeout utility sends a SIGTERM (Signal 15) to the process it is managing. SIGTERM is a “polite” termination signal; it asks the application to shut down gracefully, allowing it to save its state or write final lines to a log file. Most well-behaved Linux utilities will respond to SIGTERM and exit immediately.
However, if a process is completely frozen or specifically designed to ignore the SIGTERM signal, the timeout command will appear to fail, and the hanging process will remain active.
Enforcing a Brutal Kill (SIGKILL)
To handle stubborn processes, the timeout command includes a -k (or --kill-after) flag. This allows you to set a secondary timer. If the initial SIGTERM fails to stop the application, the secondary timer will trigger and send a SIGKILL (Signal 9). A SIGKILL cannot be ignored by the application and is enforced immediately by the Linux kernel, destroying the process instantly.
The syntax involves specifying two durations: the initial polite timeout, and the brutal fallback timeout.
timeout -k 5s 30s ./my_unstable_script.sh
In this example, timeout allows the script to run for 30 seconds. If the script is still running at the 30-second mark, timeout sends a polite SIGTERM. If the script is still running 5 seconds later (at the 35-second total mark), timeout sends an unblockable SIGKILL.
Capturing the Exit Status
In automated bash scripts, you often need to know why a command stopped. Did it finish successfully, did it crash with an error, or was it killed by the timeout? The timeout utility returns specific exit codes to help you determine this programmatically.
- If the command finishes successfully before the timer expires,
timeoutreturns 0. - If the command crashes before the timer expires,
timeoutreturns the exit code of that specific command. - If the timer expires and
timeoutis forced to kill the process, it returns 124.
You can check the exit status by inspecting the $? variable immediately after the command runs in your script:
timeout 10s ping 8.8.8.8
if [ $? -eq 124 ]; then
echo "The ping command timed out."
fi