Guide
Bash-Scripting
Beginner
Loops
for, while, and until loops in Bash — iterating over lists, files, command output, and ranges, plus break and continue.
for Loops
# Iterate over a fixed list
for env in dev staging production; do
echo "Deploying to $env"
done
# Iterate over a numeric range
for i in {1..5}; do
echo "Attempt $i"
done
# C-style for loop
for ((i = 0; i < 5; i++)); do
echo "Index: $i"
done
# Iterate over files matching a glob
for file in /var/log/*.log; do
echo "Processing $file"
done
# Iterate over an array
SERVERS=("web1" "web2" "web3")
for server in "${SERVERS[@]}"; do
echo "Checking $server"
done
while Loops
COUNT=0
while [ "$COUNT" -lt 5 ]; do
echo "Count: $COUNT"
((COUNT++))
done
# Reading a file line by line — the standard, correct pattern
while IFS= read -r LINE; do
echo "Line: $LINE"
done < servers.txt
# Infinite loop with a break condition — common for polling
while true; do
if curl -sf http://localhost:8080/health > /dev/null; then
echo "Service is healthy"
break
fi
echo "Waiting for service..."
sleep 2
done
until Loops (Inverse of while)
COUNT=0
until [ "$COUNT" -ge 5 ]; do
echo "Count: $COUNT"
((COUNT++))
done
until runs while the condition is false — the exact inverse of while. Useful for “keep retrying until success” patterns.
until curl -sf http://localhost:8080/health > /dev/null; do
echo "Service not ready, retrying..."
sleep 2
done
echo "Service is up!"
break and continue
for i in {1..10}; do
if [ "$i" -eq 5 ]; then
break # exit the loop entirely
fi
echo "$i"
done
for i in {1..10}; do
if (( i % 2 == 0 )); then
continue # skip to the next iteration
fi
echo "$i" # only odd numbers print
done
Looping Over Command Output
for pid in $(pgrep nginx); do
echo "nginx process: $pid"
done
# Safer for filenames with spaces: use a while+read loop with process substitution
while IFS= read -r line; do
echo "Found: $line"
done < <(find /var/log -name "*.log")
A Real-World Retry Loop
MAX_RETRIES=5
RETRY=0
until curl -sf https://api.example.com/health > /dev/null; do
((RETRY++))
if [ "$RETRY" -ge "$MAX_RETRIES" ]; then
echo "Failed after $MAX_RETRIES attempts" >&2
exit 1
fi
echo "Retry $RETRY/$MAX_RETRIES..."
sleep $((RETRY * 2)) # exponential-ish backoff
done
echo "Service is healthy"
Production Considerations
- For iterating over command output that might contain filenames with spaces, prefer
while readwith process substitution (< <(command)) overfor x in $(command), which word-splits on whitespace and breaks. - Always cap retry loops with a maximum attempt count — an unconditional
while trueretry loop with no exit condition can hang a script (and a pipeline) forever. - Add
sleepbetween polling iterations to avoid hammering a service or API with a tight, CPU-spinning loop.
Quick Interview Answer
“
foriterates over a fixed list, range, glob, or array;whilerepeats as long as a condition is true, commonly used for reading files line-by-line or polling until a service is healthy;untiliswhile’s inverse, useful for ‘retry until success’ patterns.breakexits a loop entirely,continueskips to the next iteration. For command output that might contain spaces,while readwith process substitution is safer thanfor x in $(cmd).”
Common Mistakes
- Using
for x in $(command)on output that might contain spaces or special characters, causing incorrect word-splitting. - Writing an unbounded retry loop with no maximum attempt count or timeout.
- Forgetting
IFS=and-rwhen reading files line-by-line, silently mangling whitespace and backslashes.
Add More Questions to This Guide
Know a question that should be here? Share it and help the community!
Open Google Form