Loops are where Bash scripts shift from one-off commands to repeatable processing. The key is choosing the right loop for the data and stop condition you have.
Table of Contents
This post focuses on practical loop patterns that are safe and readable.
for Loops
while and until Loops
Loop Control Statements
Series Navigation
for loops
Iterate fixed value sets
A for loop is ideal when iterating known values.
for env_name in dev stage prod; do
echo "processing environment: $env_name"
doneYou can also iterate file globs:
for file in ./*.log; do
echo "log file: $file"
doneUse C style arithmetic loops
This style is useful for index-based logic.
for ((i=1; i<=5; i++)); do
echo "attempt $i"
donewhile and until loops
Read files line by line
Use while IFS= read -r line to preserve whitespace and backslashes.
while IFS= read -r line; do
echo "line: $line"
done < server-list.txtAvoid piping into while read when you need loop side effects outside the loop scope.
Retry with until
until loops run until a command succeeds.
attempt=0
until curl -fsS https://thelinux.pro >/dev/null; do
attempt=$((attempt + 1))
echo "health check failed on attempt $attempt"
sleep 2
done
echo "service is reachable"Loop control statements
Break out early
break exits the current loop as soon as a condition is met.
for host in web1 web2 web3; do
if ping -c 1 "$host" >/dev/null 2>&1; then
echo "first reachable host: $host"
break
fi
doneSkip one iteration with continue
continue skips only the current item and keeps looping.
while IFS= read -r filename; do
[[ -z "$filename" ]] && continue
[[ "$filename" == \#* ]] && continue
echo "processing: $filename"
done < deploy-files.txtPractical script example
#!/usr/bin/env bash
success_count=0
for target in "$@"; do
if [[ ! -f "$target" ]]; then
echo "missing file: $target"
continue
fi
echo "valid file: $target"
success_count=$((success_count + 1))
done
echo "processed $success_count valid files"Next in this series
Next, we will finish the series with functions, set -euo pipefail, trap, and script structure patterns that make Bash code maintainable in production.