timeout Command: Limiting Command Execution Time
What You'll Learn
- How to limit how long a command runs with
timeout - How to automatically stop a command that "hangs and never returns"
- How to detect a timeout using exit status
124 - How to force-kill a stubborn process that ignores SIGTERM with
-k
Quick Summary (the patterns to remember first)
- Run with a time limit →
timeout 10 command(stops after 10 seconds) - Add a unit if you like →
timeout 30s/timeout 5m/timeout 1h - Detect a timeout → exit status of
124means it timed out - Still won't stop →
timeout -k 5 10 command(force-kill after a grace period)
1. What Is the timeout Command?
Conclusion:
timeoutautomatically ends a command once it exceeds a time limit you set. It's the go-to tool for preventing hangs.
Ctrl+C. Is that the only way to stop it?timeout helps. It lets you set a time limit: "run this command for at most N seconds, and stop it automatically if it goes over."Ctrl+C myself? It stops on its own?timeout is your safety net.The basic idea of timeout
timeout 10 command
↑ ↑
| the command you want to run
time limit (seconds)"Finish within 10 seconds and it ends normally; go over and it's forcibly stopped."
2. Why Do You Need timeout?
Conclusion: A command that hangs on a network wait or an infinite loop can freeze your whole script. timeout prevents that.
Ctrl+C. But a cron job or automation script has nobody watching. The hung process lingers and the next step never starts. With timeout you set an upper bound, so at worst it "gives up after N seconds and moves on."A hung command left alone can eat up memory or process slots, or cause overlapping cron runs. "Put a time limit on anything that might not finish" is the safe way to operate.
3. Basic Usage (Specifying the Time)
Conclusion: The form is
timeout DURATION command. A bare number means seconds; adds/m/h/dfor units.
The most basic form is:
$ timeout 10 sleep 30
sleep 30 normally waits 30 seconds. But with timeout 10, it's stopped after 10 seconds.
sleep 30! It stopped earlier than the promised 30 seconds.You can attach a unit (suffix) to the duration.
$ timeout 30s command # 30 seconds $ timeout 5m command # 5 minutes $ timeout 1h command # 1 hour $ timeout 2d command # 2 days
Duration units (suffixes)
| Form | Meaning |
|---|---|
10 |
10 seconds (no unit = seconds) |
30s |
30 seconds |
5m |
5 minutes |
1h |
1 hour |
2d |
2 days |
Decimals work too (timeout 0.5 command for 0.5 seconds).
4. Detecting Timeouts with Exit Status 124
Conclusion: When timeout cuts a command off, the exit status is
124. Ifecho $?shows124, it timed out.
When timeout stops a command because the time ran out, the exit status becomes 124. Checking this lets you detect a timeout mechanically.
$ timeout 1 sleep 10 $ echo $?
124
124 showed up. So that's the sign of a timeout.0 for success, for example. So checking for 124 tells you whether it was "cut off partway through" or "finished properly."If it finishes in time, the command's own status is returned.
$ timeout 10 sleep 1 $ echo $?
0
Exit statuses worth knowing
| Value | Meaning |
|---|---|
124 |
Cut off by a timeout |
125 |
The timeout command itself failed |
126 |
Command found but could not run |
127 |
Command not found |
137 |
Force-killed by the KILL signal (-k) (128 + 9) |
For now, just remember "124 = timed out."
5. Force-Killing Stubborn Processes with -k
Conclusion: timeout sends SIGTERM by default. If that's ignored, use
-k DURATIONto send SIGKILL after a grace period and stop it for sure.
timeout. Why is that?timeout first sends a SIGTERM (a polite request to quit) to the command. But some programs ignore that request, so they don't stop.-k (kill-after). You set up a two-stage approach: "if it still hasn't stopped N seconds after the first request, force-kill it (SIGKILL)."$ timeout -k 5 10 command
This means:
- First, after 10 seconds, send SIGTERM (the polite request) to the command
- If it still isn't stopped after another 5 seconds, send SIGKILL (force-kill)
How -k (kill-after) works
timeout -k 5 10 command
↑ ↑
| the real time limit (10s) → SIGTERM
extra grace (5s) → SIGKILL if still runningA program cannot refuse SIGKILL. It's the last resort when you must stop it for sure.
SIGKILL (force-kill) stops the process without giving it a chance to clean up. A file being written may end up corrupted, so try a plain timeout (SIGTERM) first and use -k as a backup only when it won't stop.
6. Specifying the Signal (-s)
Conclusion: Use
-sto change the signal sent. If you want the command's own status returned on timeout, use--preserve-status.
By default SIGTERM is sent, but you can specify a different signal with -s (--signal).
$ timeout -s SIGINT 10 command
This sends SIGINT, the same as Ctrl+C. Some commands shut down more gracefully with this than with SIGTERM.
timeout are the polite SIGTERM (default), SIGINT (like Ctrl+C), and the last-resort SIGKILL. Signals themselves go a bit deep, so we'll cover them properly in another article (trap basics).When you want the command's own exit status returned instead of 124 on timeout, use --preserve-status.
$ timeout --preserve-status 10 command
Use --preserve-status when you care about the value the command returned more than whether it timed out. Normally it's simpler to leave it off and check for 124.
7. Common Beginner Mistakes
Conclusion: It's easy to mix up the order of duration and command, the meaning of
124, and the argument order for-k.
7-1. Reversing the order of duration and command
# NG: the command comes first $ timeout sleep 30 10 # OK: duration → command $ timeout 10 sleep 30
A duration must always come right after timeout. Then write the command you want to run. Reverse the order and timeout errors out.
7-2. Mistaking 124 for an "error"
124 first appeared, I panicked and thought "the command broke!"124 is actually proof that timeout did its job on schedule. It's not a defect in the command — it means "it didn't finish in time, so I cut it off as planned." No need to panic.7-3. Thinking you limited the whole pipeline when only part is limited
# This does not limit the whole pipeline $ timeout 10 grep pattern file | sort
Only the timeout 10 grep pattern file part is limited; | sort is treated separately. To wrap an entire pipeline at once, use bash -c.
$ timeout 10 bash -c 'grep pattern file | sort'
8. Mini Exercises: Try It Yourself
Conclusion: Three tasks — cut off, check exit status, force-kill — to feel out timeout by hand.
sleep makes it safe to experiment.Task 1: Cut off sleep 30 after 3 seconds.
Show hint
The form is timeout DURATION command. A bare number means seconds.
Sample answer
$ timeout 3 sleep 30
Task 2: Right after Task 1, print the exit status and confirm it's 124 (timed out).
Show hint
The previous result is in $?.
Sample answer
$ timeout 3 sleep 30 $ echo $?
Seeing 124 means the timeout worked.
Task 3: Write a command that stops sleep 30 with "SIGTERM at 5 seconds, then SIGKILL if it's still running 2 seconds later."
Show hint
The order is -k GRACE LIMIT command.
Sample answer
$ timeout -k 2 5 sleep 30
9. Copy-Paste Templates
Conclusion: Keep the common patterns — basic, with units, detection, force-kill, pipeline — handy.
Common patterns to keep on hand
# Basic: stop after 10 seconds timeout 10 command # Add a unit (seconds / minutes) timeout 30s command timeout 5m command # Detect a timeout (124 means timed out) timeout 10 command echo $? # Force-kill if it won't stop (10s + 5s grace, then SIGKILL) timeout -k 5 10 command # Limit an entire pipeline timeout 10 bash -c 'commandA | commandB' # Stop with SIGINT (like Ctrl+C) timeout -s SIGINT 10 command