DevOps Journey
Bash

Loops

Loops and iteration in Bash

Loops

Loops allow you to repeat commands multiple times.

For Loop

Loop Through List

# Loop through values
for item in apple banana orange; do
    echo "Fruit: $item"
done

# Loop through array
fruits=("apple" "banana" "cherry")
for fruit in "${fruits[@]}"; do
    echo "$fruit"
done

# Loop through command output
for file in $(ls); do
    echo "File: $file"
done

# Loop through glob pattern
for script in *.sh; do
    echo "Script: $script"
done

C-Style For Loop

# C-style for loop
for ((i=0; i<5; i++)); do
    echo "Count: $i"
done

# Reverse counting
for ((i=5; i>0; i--)); do
    echo "Count: $i"
done

# With step
for ((i=0; i<=10; i+=2)); do
    echo "Even: $i"
done

While Loop

# Basic while loop
count=0
while [ $count -lt 5 ]; do
    echo "Count: $count"
    ((count++))
done

# Read lines from file
while IFS= read -r line; do
    echo "Line: $line"
done < file.txt

# Read from command
ls | while read line; do
    echo "Item: $line"
done

# Infinite loop with break
while true; do
    echo "Doing something..."
    if [ condition ]; then
        break # exit loop
    fi
done

Until Loop

# Until loop (opposite of while)
count=0
until [ $count -eq 5 ]; do
    echo "Count: $count"
    ((count++))
done

Loop Control

# Break - exit loop
for i in 1 2 3 4 5; do
    if [ $i -eq 3 ]; then
        break # exit for loop
    fi
    echo $i
done

# Continue - skip to next iteration
for i in 1 2 3 4 5; do
    if [ $i -eq 3 ]; then
        continue # skip this iteration
    fi
    echo $i
done

# Nested loops with labeled break (bash 4+)
for i in 1 2 3; do
    for j in a b c; do
        if [ $i -eq 2 ] && [ $j = "b" ]; then
            break 2 # break out of both loops
        fi
        echo "$i-$j"
    done
done

Iterating Through Arguments

#!/bin/bash

# Loop through command-line arguments
for arg in "$@"; do
    echo "Argument: $arg"
done

# Loop with index
for ((i=0; i<$#; i++)); do
    echo "Arg $i: ${!i}"
done

Practical Examples

Process Files

#!/bin/bash

# Process all .log files
for logfile in *.log; do
    if [ -f "$logfile" ]; then
        lines=$(wc -l < "$logfile")
        echo "$logfile: $lines lines"
    fi
done

Retry Logic

#!/bin/bash

max_attempts=3
attempt=0

while [ $attempt -lt $max_attempts ]; do
    echo "Attempt $((attempt+1))..."

    if command_to_execute; then
        echo "Success!"
        break
    fi

    ((attempt++))
    if [ $attempt -lt $max_attempts ]; then
        sleep 5 # wait before retry
    fi
done

if [ $attempt -eq $max_attempts ]; then
    echo "Failed after $max_attempts attempts"
    exit 1
fi

Parallel Processing

#!/bin/bash

# Process items in parallel
for item in item1 item2 item3; do
    (
        # Run in subshell (parallel)
        process_item "$item"
    ) &
done

# Wait for all background jobs
wait
echo "All items processed"
#!/bin/bash

while true; do
    echo "Menu:"
    echo "1. Option 1"
    echo "2. Option 2"
    echo "3. Exit"
    read -p "Select option: " choice

    case $choice in
        1) echo "You selected option 1" ;;
        2) echo "You selected option 2" ;;
        3) echo "Exiting..."; break ;;
        *) echo "Invalid option" ;;
    esac
done

Best Practices

  • Use meaningful loop variables
  • Always quote array expansion: "${array[@]}"
  • Use local in functions with loop variables
  • Be careful with infinite loops
  • Use break and continue judiciously
  • For large iterations, consider performance
  • Use for (( )) for numeric loops
  • Avoid modifying loop variables within loop body
  • Consider using find for file iteration instead of globbing

On this page