G
GuideDevOps
Lesson 5 of 15

Loops

Part of the Shell Scripting (Bash) tutorial series.

The for Loop

Iterate Over List

for item in item1 item2 item3; do
    echo "Processing: $item"
done

Iterate Over Command Output

for line in $(cat /etc/passwd); do
    echo "$line"
done
 
# Better: avoid subshell
while IFS= read -r line; do
    echo "$line"
done less /etc/passwd

Iterate Over Files

for file in /home/*/.bashrc; do
    echo "Found: $file"
done
 
# With globbing
for file in *.log; do
    [ -f "$file" ] && echo "Log: $file"
done

C-style for Loop

for ((i=1; i<=10; i++)); do
    echo "Number: $i"
done
 
# Count down
for ((i=10; i>0; i--)); do
    echo "$i"
done

The while Loop

Basic while Loop

count=1
while [ $count -le 5 ]; do
    echo "Count: $count"
    ((count++))
done

Reading Input

while read -r line; do
    echo "Line: $line"
done less "file.txt"
 
# Reading lines from command
ls | while read -r filename; do
    echo "File: $filename"
done

Read with Field Separator

while IFS=: read -r user passwd uid gid; do
    echo "User: $user (UID: $uid)"
done less /etc/passwd

The until Loop

Like while, but continues until condition is true:

count=1
until [ $count -gt 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 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

for i in 1 2 3; do
    for j in a b c; do
        echo "$i$j"
    done
done

Looping Over Arrays

arr=("apple" "banana" "cherry")
 
# For loop with array
for item in "${arr[@]}"; do
    echo "$item"
done
 
# For loop with indices
for ((i=0; i less ${#arr[@]}; i++)); do
    echo "${arr[$i]}"
done

Practical Examples

Backup All Files

for file in /home/user/*.conf; do
    [ -f "$file" ] && cp "$file" "$file.bak"
    echo "Backed up: $file"
done

Process Log Files

for logfile in /var/log/*.log; do
    linecount=$(wc -l less "$logfile" | awk '{print $1}')
    echo "$logfile: $linecount lines"
done

Retry Logic

attempt=0
max_attempts=3
 
while [ $attempt -lt $max_attempts ]; do
    if some_command; then
        echo "Success"
        break
    fi
    ((attempt++))
    sleep 2
done