Automated shell scripts, scheduled cron jobs, and CI/CD deployment pipelines frequently execute external network commands, database queries, or third-party binaries. When a remote server stops responding, a network socket hangs, or a process enters an infinite loop, unmonitored scripts can freeze indefinitely, blocking server resources and halting deployment workflows.
The timeout command—part of GNU Coreutils and available across all standard Linux distributions—provides a robust safeguard. By executing any command with an explicit time limit, timeout guarantees that unresponsive tasks are terminated cleanly if they exceed their allotted runtime. In this guide, we explore syntax, duration formatting, signal management, and practical automation examples.
How the timeout Command Operates
The timeout utility launches a child process and monitors its execution against a timer. If the command finishes naturally before the deadline, timeout exits with the command’s original status code. If the timer expires, timeout dispatches a termination signal:
| Parameter / Flag | Function | Practical Application |
|---|---|---|
DURATION |
Time ceiling (supports seconds, minutes, hours, days) | Defining execution boundaries (e.g., 10s, 5m, 1h) |
-s, --signal |
Specifies the initial signal sent upon expiry | Sending SIGINT or SIGHUP instead of default SIGTERM |
-k, --kill-after |
Secondary forceful kill signal if process refuses to exit | Dispatches SIGKILL (signal 9) if child ignores SIGTERM |
--preserve-status |
Preserves child exit code upon termination | Simplifying status checking in automated shell scripts |
When tracking active processes managed by timeout, pairing execution limits with pgrep and pkill in Linux gives administrators total control over running daemons.
Basic Syntax and Duration Suffixes
The fundamental syntax requires only a duration followed by the command you wish to execute:
timeout DURATION COMMAND [ARGUMENTS...]
You can specify durations with explicit unit suffixes:
s— Seconds (default if no suffix provided):timeout 10 ping 8.8.8.8m— Minutes:timeout 5m ./backup_database.shh— Hours:timeout 2h rsync -av /data /backupd— Days:timeout 1d ./intensive_simulation.bin
Handling Unresponsive Processes with –kill-after (-k)
By default, timeout sends SIGTERM (signal 15) when the deadline passes, requesting a graceful shutdown. However, certain hanging processes or deadlocked threads ignore SIGTERM. To ensure a process is terminated regardless of its state, use the -k flag:
timeout -k 5s 30s ./risky_script.sh
In this example, if risky_script.sh is still running after 30 seconds, timeout sends SIGTERM. If the script fails to shut down within an additional 5 seconds, timeout dispatches an uncatchable SIGKILL (signal 9), immediately halting the process.
Sending Custom Signals with -s
If your application requires a specific POSIX signal (such as SIGINT to simulate Ctrl + C, or SIGUSR1 to dump debug logs before exit):
timeout -s SIGINT 15s tcpdump -i eth0 -w capture.pcap
This allows tcpdump to close its pcap file cleanly and write final packet counts before terminating.
Understanding Exit Status Codes in Shell Scripts
In automation scripts, knowing why a command ended is vital for error handling:
- Exit code 0: Command completed successfully before timeout expired.
- Exit code 124: The command timed out and was killed by
timeout. - Exit code 137: The command timed out and was forcefully killed with
SIGKILL(128 + 9). - Command’s natural error code: If the command failed on its own before timing out (e.g., 1 or 2).
Example bash script implementation:
timeout 10s curl -s https://api.example.com/health > /dev/null
STATUS=$?
if [ $STATUS -eq 124 ]; then
echo "Warning: API health check timed out!"
elif [ $STATUS -eq 0 ]; then
echo "API is healthy and responsive."
else
echo "API returned error code: $STATUS"
fi
When diagnosing root causes behind recurring script timeouts, pairing your analysis with the strace command in Linux reveals internal system calls and hanging network sockets in real time.
Frequently Asked Questions
Does timeout kill child processes spawned by the command?
By default, timeout sends the signal only to the direct child process. If the command spawns child background processes, they might continue running. To terminate an entire process group, run timeout in a new process group or combine it with pkill -P.
Can timeout be used with shell aliases or built-in functions?
Because timeout is an external binary, it cannot directly invoke shell built-ins (like cd) or aliases. To time a shell function, wrap it inside a subshell: timeout 5s bash -c 'my_function'.
Is the timeout command available on macOS?
macOS does not include GNU timeout by default. Mac users can install GNU coreutils via Homebrew (brew install coreutils) and invoke it as gtimeout.