while and until Loops — Condition-Based Iteration
Loop as long as a condition is true (while) or until it becomes true (until). Learn polling loops, reading files line-by-line, and infinite loops with controlled exits.
The while loop runs a block of commands as long as a condition (command) exits successfully. Its inverse, until, runs until a condition succeeds. These are the go-to loops when you don't know in advance how many iterations you need.
while Loop Basics
# Basic while loop
count=1
while [[ $count -le 5 ]]; do
echo "Count: $count"
(( count++ ))
done
# while with arithmetic condition (cleaner for numbers)
i=10
while (( i > 0 )); do
echo "$i"
(( i-- ))
done
# while true — infinite loop (exit with break)
while true; do
echo "Press Ctrl+C to stop"
sleep 1
doneReading a File Line by Line
The most important use of while in Bash is processing a file one line at a time:
# Read /etc/hosts line by line
while IFS= read -r line; do
echo "Line: $line"
done < /etc/hosts
# Read from command output
while IFS= read -r line; do
echo "Processing: $line"
done < <(grep "ERROR" /var/log/syslog)
# Explanation of the idioms:
# IFS= — don't strip leading/trailing whitespace
# read -r — don't interpret backslashes as escapes
# < file — redirect file to the while loop's stdin
# < <(command) — redirect command output (process substitution)IFS= and read -r are not optional
Without IFS=, read strips leading and trailing whitespace from each line — breaking indented or whitespace-significant content.
Without -r, backslashes are treated as escape characters — a line ending in \ gets joined with the next line.
Always use while IFS= read -r line as the canonical form.
until Loop
# until runs until condition is TRUE (opposite of while)
count=1
until [[ $count -gt 5 ]]; do
echo "Count: $count"
(( count++ ))
done
# Polling — wait until file appears
until [[ -f /tmp/ready.flag ]]; do
echo "Waiting for ready.flag..."
sleep 2
done
echo "Ready!"Polling and Retry Loops
#!/usr/bin/env bash
# Wait for a service to respond, with timeout
max_attempts=10
attempt=0
host="localhost"
port=8080
while true; do
(( attempt++ ))
if nc -z "$host" "$port" 2>/dev/null; then
echo "Service is up after $attempt attempts"
break
fi
if (( attempt >= max_attempts )); then
echo "Service did not start after $max_attempts attempts" >&2
exit 1
fi
echo "Attempt $attempt/$max_attempts — waiting..."
sleep 3
donewhile with Multiple Conditions
# AND condition
a=1 b=10
while [[ $a -lt 5 && $b -gt 3 ]]; do
echo "a=$a, b=$b"
(( a++ ))
(( b -= 2 ))
done
# Read multiple fields per line (IFS splits into variables)
while IFS=: read -r user pass uid gid gecos home shell; do
echo "User: $user, Shell: $shell"
done < /etc/passwdWhen is `until condition` the right choice over `while condition`?
Write a script retry.sh that:
- Takes a command as argument(s) (e.g.,
./retry.sh curl https://example.com) - Runs the command up to 5 times
- If it succeeds (exit code 0), print "Success on attempt N" and stop
- If all 5 attempts fail, print "Failed after 5 attempts" and exit 1
- Wait 2 seconds between attempts