How to Use the timeout Command in Linux to Run Commands with Time Limits

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.8
  • m — Minutes: timeout 5m ./backup_database.sh
  • h — Hours: timeout 2h rsync -av /data /backup
  • d — 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.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.