Shell Script Loop Examples

Loops are fundamental building blocks of shell scripts. Bash provides for loops (over lists and ranges), while loops (condition-based), and until loops (run until condition is true). Mastering these patterns lets you automate repetitive tasks, process files in bulk, and build robust automation scripts.

ShellBashLoopsScripting
For Loops
Loop over a list of items
for fruit in apple banana cherry; do
  echo "Processing: $fruit"
done
The simplest for loop iterates over a space-separated list of items. Each item is assigned to the variable (here fruit) in turn. The loop body runs once for each item between do and done.
Numeric range loop (C-style)
for ((i=1; i<=5; i++)); do
  echo "Step $i of 5"
done
The C-style for loop uses double parentheses and supports standard C loop syntax: initializer; condition; increment. Ideal for counting loops where you need a numeric index. Bash-specific (not POSIX sh).
Loop over files matching a pattern
for file in *.txt; do
  echo "Processing $file"
  wc -l "$file"
done
Shell glob expansion (wildcards) in a for loop iterates over matching files. Always quote the variable "$file" to handle filenames with spaces correctly. If no files match, the glob is passed literally — add shopt -s nullglob to avoid this.
Loop over command output
for user in $(cat users.txt); do
  echo "Creating account for $user"
done
Use command substitution $() to loop over the output of a command. This splits on whitespace by default. For lines with spaces, use while read instead (see below) which handles spaces in values correctly.
While & Until Loops
Basic while loop with counter
count=1
while [ $count -le 5 ]; do
  echo "Count: $count"
  ((count++))
done
A while loop runs as long as the condition is true. This example counts from 1 to 5. The [ ] test uses -le (less than or equal). Use (( )) for arithmetic operations on the counter.
Read a file line by line
while IFS= read -r line; do
  echo "Line: $line"
done < filename.txt
The safest way to process a file line by line. IFS= prevents leading/trailing whitespace from being stripped. -r prevents backslash interpretation. The < redirects the file to the while loop's stdin.
Wait until a condition is true
until curl -sf http://localhost:8080/health; do
  echo "Waiting for service..."
  sleep 2
done
echo "Service is up!"
An until loop is the inverse of while: it runs until the condition becomes true (exits with code 0). This example polls a health endpoint every 2 seconds until the service is ready. Essential in deployment and startup scripts.
Loop Control
Break out of a loop
for i in 1 2 3 4 5; do
  if [ $i -eq 3 ]; then
    break
  fi
  echo "$i"
done
# Output: 1 2
break immediately exits the innermost loop. In nested loops, break 2 exits two levels up. Use break when you've found what you're looking for and don't need to continue iterating.
Skip an iteration with continue
for i in 1 2 3 4 5; do
  if [ $i -eq 3 ]; then
    continue
  fi
  echo "$i"
done
# Output: 1 2 4 5
continue skips the rest of the current iteration and moves to the next one. Use it to skip invalid items, error conditions, or items that don't match your criteria without breaking the entire loop.
Loop with array elements
servers=("web1" "web2" "db1" "cache1")
for server in "${servers[@]}"; do
  echo "Deploying to: $server"
done
Use "${array[@]}" to expand all array elements as separate quoted words. The double quotes and @ together ensure elements with spaces are handled correctly. This is the standard pattern for iterating over bash arrays.

How to Use

  1. Use for item in list; do ... done for iterating over known items or files.
  2. Use while condition; do ... done when the number of iterations is not known upfront.
  3. Use while IFS= read -r line; do ... done < file for safe line-by-line file processing.
  4. Always quote variables inside loops to handle spaces in filenames and values.

Frequently Asked Questions

What is the difference between for and while loops in bash?

for loops iterate over a finite list (array, files, command output). while loops repeat as long as a condition is true, making them suitable for indefinite loops like polling or reading streams. Use for when you know the items to iterate; use while for condition-based repetition.

Why should I use while read instead of for to process file lines?

A for loop with command substitution splits on all whitespace (spaces, tabs, newlines) and can break lines with spaces into multiple iterations. while IFS= read -r line reads exactly one line at a time, preserving spaces within lines and handling all edge cases correctly.

How do I loop in parallel in bash?

Append & inside the loop to run each iteration as a background job, then use wait after the loop: for f in *.log; do process "$f" & done; wait. For more control over parallelism, use xargs -P N or the GNU parallel command.

Related Tools