In this lesson, you will learn how to prevent your Bash scripts from hanging indefinitely by implementing time-out logic around slow or unresponsive commands.
The Problem: The Infinite Hang
In Linux, some commands—like network requests, hardware queries, or waiting for user input—don't always finish. If a command freezes, your script stops dead in its tracks. Because Bash is generally synchronous, it will wait forever for a process to return an exit code. To build robust scripts, we need a way to say: "Run this command, but if it takes longer than seconds, kill it and move on."
The Solution: Using timeout
The cleanest pattern for non-blocking execution is the timeout command. It wraps your command and manages the process lifecycle, ensuring that if the time limit is reached, it terminates the child process and returns a specific exit code (usually 124).
Consider a script trying to ping a server that might be down:
# Try to reach a server for 3 seconds
if timeout 3s ping -c 1 192.0.2.1 > /dev/null; then
echo "Server responded!"
else
# Check if it failed because of the time-out
if [ $? -eq 124 ]; then
echo "Command timed out."
else
echo "Command failed for other reasons."
fi
fi
How it works
- The Wrapper:
timeoutacts as a supervisor. It forks your command into a child process and tracks its execution time. - Termination: If the timer expires before the command completes,
timeoutsends aSIGTERM(and later aSIGKILLif necessary) to the child process. - Exit Code Propagation: By capturing the exit code of the
timeoutcommand itself, you can distinguish between a successful run, a standard command failure, and a forced termination.
This pattern is essential when you have multiple tasks. By using timeout in conjunction with your previous knowledge of background processes (Lesson 12), you can launch several non-blocking tasks simultaneously, ensuring that one unresponsive network call doesn't prevent your entire orchestration script from completing its work.
Key Takeaway: Always wrap volatile or network-dependent commands in timeout to ensure your script maintains control over its own execution time.