Timeouts and Long-Running Commands
A command that can wait forever can block a deployment forever. Timeouts convert indefinite waiting into explicit failure behavior, but they need careful status interpretation and retry policy.
Learning objectives
By the end of this lesson
- Apply wall-clock deadlines.
- Distinguish timeout from ordinary failure.
- Use graceful escalation.
- Prefer tool-native timeout controls.
- Separate attempt timeout from retry budget.
1. Long-running operations need upper bounds
A network request, package operation, remote command, or health probe can hang longer than the surrounding automation can tolerate. Define a maximum duration.
2. GNU timeout wraps a command with a wall-clock deadline
timeout 10s curl --fail --silent --show-error \
https://example.invalid/healthtimeout is common on Linux through GNU coreutils but is not guaranteed on every BSD/macOS or minimal environment.
3. Distinguish timeout from ordinary command failure
if timeout 5s long_operation; then
printf 'operation succeeded\n'
else
status=$?
case $status in
124) printf 'operation timed out\n' >&2 ;;
*) printf 'operation failed status=%d\n' "$status" >&2 ;;
esac
fiGNU timeout commonly uses 124 for a deadline expiration. Document the implementation your script targets.
4. Prefer graceful termination before force
timeout --signal=TERM 30s long_running_commandA graceful signal gives the child an opportunity to flush state and clean up.
5. Escalate after a grace period if necessary
timeout --signal=TERM --kill-after=5s 30s \
long_running_commandThis requests graceful termination first, then escalates if the process remains alive.
6. Prefer application-native timeout controls
curl \
--connect-timeout 5 \
--max-time 30 \
--fail \
--silent \
--show-error \
"$url"Native timeout options often understand protocol phases better than a generic process deadline.
7. Timeout layers solve different problems
8. Bounded work still needs useful logs
printf 'backup start=%(%FT%T%z)T\n' -1 >&2
if timeout 30m backup_database; then
printf 'backup complete\n' >&2
else
status=$?
printf 'backup failed status=%d\n' "$status" >&2
exit "$status"
fi9. Timeout and retry are separate policies
A timeout decides when one attempt ends. Retry policy decides whether another attempt is justified.
Three 30-second attempts can consume far more than 30 seconds. Define an overall time budget as well as per-attempt limits.
10. Avoid hand-rolled timeout machinery unless necessary
A custom timer plus background child introduces race conditions, signal forwarding, and status-accounting complexity. Prefer a trusted platform utility when your support matrix includes it.
11. Hands-on lab: bounded command wrapper
mkdir -p "$HOME/devops-academy/bash/chapter10/lesson04"
cd "$HOME/devops-academy/bash/chapter10/lesson04"
run_bounded() {
local seconds=$1
shift
if timeout "${seconds}s" "$@"; then
printf 'RESULT=success\n'
else
status=$?
if (( status == 124 )); then
printf 'RESULT=timeout after %ss\n' "$seconds" >&2
else
printf 'RESULT=failure status=%d\n' "$status" >&2
fi
return "$status"
fi
}
if command -v timeout >/dev/null 2>&1; then
run_bounded 3 bash -c 'sleep 1; echo quick'
run_bounded 1 bash -c 'sleep 3; echo late' || true
else
printf 'timeout utility unavailable\n' >&2
fiVerification checklist
12. Knowledge check
Question 1. What does a timeout provide?
Question 2. Why prefer native tool timeouts?
Question 3. Does timeout automatically imply retry?
Question 4. Why use a TERM-then-KILL escalation?
13. Summary
Timeouts convert indefinite waiting into explicit failure. Prefer native deadlines, add a reliable outer bound when necessary, distinguish timeout status, and design retry policy around a total time budget.
14. Further reading
- GNU Coreutils manual — timeout.
- curl documentation — timeout options.
- GNU Bash Reference Manual — status and signals.
- POSIX process-control concepts.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this address.