Przejdลบ do treล›ci

๐Ÿ” Extended Loops and Iteration

Loops enable repetition โ€” processing files, retrying operations, iterating over data. This section covers all major loop types and their practical applications.

๐Ÿงญ For Loop Basics

Iterating Over Items

1
2
3
for item in apple banana cherry; do
    echo "Processing: $item"
done

Output:

1
2
3
Processing: apple
Processing: banana
Processing: cherry

Iterating Over Files

1
2
3
4
for file in *.txt; do
    [ -e "$file" ] || continue   # Skip if no matches
    echo "Found: $file"
done

โš ๏ธ Without [ -e "$file" ], if no .txt files exist, the loop runs once with literal *.txt.


๐Ÿงช Numeric Ranges

Bash/Zsh C-Style Loop

1
2
3
for ((i=1; i<=5; i++)); do
    echo "Number: $i"
done

Output: 1, 2, 3, 4, 5

POSIX-Compatible Range

1
2
3
4
5
i=1
while [ $i -le 5 ]; do
    echo "Number: $i"
    i=$((i + 1))
done

Using seq (Portable)

1
2
3
for i in $(seq 1 5); do
    echo "Number: $i"
done

Or with brace expansion (Bash/Zsh):

1
2
3
for i in {1..5}; do
    echo "Number: $i"
done

๐Ÿง  While Loop

Repeat while condition is true:

1
2
3
4
5
counter=0
while [ $counter -lt 5 ]; do
    echo "Count: $counter"
    counter=$((counter + 1))
done

Reading Input Line by Line

This is one of the most common patterns:

1
2
3
while IFS= read -r line; do
    echo "Line: $line"
done < input.txt

Explanation: - IFS= prevents trimming whitespace - -r prevents backslash interpretation - < input.txt redirects file into loop

Process multiple files:

1
2
3
4
5
for file in "$@"; do
    while IFS= read -r line; do
        echo "$file: $line"
    done < "$file"
done

๐Ÿงช Until Loop

Repeat until condition becomes true:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
retries=0
until [ $retries -ge 3 ]; do
    echo "Attempt $((retries + 1))"
    if curl -s https://api.example.com/health > /dev/null; then
        echo "Service is up!"
        break
    fi
    retries=$((retries + 1))
    sleep 2
done

Useful for retry logic with timeout.


๐Ÿง  Loop Control Statements

Break โ€” Exit Loop Early

1
2
3
4
5
6
for i in {1..100}; do
    if [ $i -eq 42 ]; then
        echo "Found the answer!"
        break
    fi
done

Continue โ€” Skip Current Iteration

1
2
3
4
for file in *.log; do
    [ -s "$file" ] || continue   # Skip empty files
    grep ERROR "$file"
done

Nested Loop Control

Control outer loop from inner:

1
2
3
4
5
6
7
8
for dir in */; do
    for file in "$dir"*; do
        if [ "$file" = "STOP" ]; then
            break 2   # Exit both loops
        fi
        echo "Processing: $file"
    done
done

๐Ÿงช Processing Command Output

Iterate Over Command Results

1
2
3
for pid in $(pgrep nginx); do
    echo "Nginx process: $pid"
done

โš ๏ธ Be careful with spaces in filenames โ€” use while read instead:

1
2
3
pgrep nginx | while IFS= read -r pid; do
    echo "Nginx process: $pid"
done

Process Array Elements (Bash)

1
2
3
4
servers=("web1" "web2" "db1")
for server in "${servers[@]}"; do
    ssh "$server" "uptime"
done

๐Ÿง  Practical Patterns

Batch Processing

Process files in batches of 10:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
count=0
batch=()

for file in *.dat; do
    batch+=("$file")
    count=$((count + 1))

    if [ $count -eq 10 ]; then
        process_batch "${batch[@]}"
        batch=()
        count=0
    fi
done

# Process remaining
[ ${#batch[@]} -gt 0 ] && process_batch "${batch[@]}"

Parallel Processing with Background Jobs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
for file in *.log; do
    analyze_log "$file" &
    jobs=$((jobs + 1))

    if [ $jobs -ge 4 ]; then
        wait   # Wait for all background jobs
        jobs=0
    fi
done

wait   # Final wait for remaining jobs

๐Ÿงช Select Loop (Menu System)

Bash/Zsh select creates interactive menus:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
options=("Start" "Stop" "Restart" "Quit")

select opt in "${options[@]}"; do
    case $opt in
        Start)  echo "Starting..."; break ;;
        Stop)   echo "Stopping..."; break ;;
        Restart) echo "Restarting..."; break ;;
        Quit)   echo "Goodbye"; exit 0 ;;
        *)      echo "Invalid option" ;;
    esac
done

๐Ÿงพ Performance Considerations

Pattern Performance Notes
for i in $(seq) โš ๏ธ Slow Spawns subshell
for ((i=0; i<N; i++)) โœ… Fast Built-in arithmetic
while read โœ… Fast No subshell for input
for file in * โš ๏ธ Medium Glob expansion can be slow
find ... -print0 \| xargs โœ… Fast Handles many files efficiently

๐Ÿงพ Summary

  • Use for for known sets, while for unknown durations.
  • Always quote variables in loops: "$item" not $item.
  • Use break and continue for fine control.
  • Prefer while IFS= read -r for line-by-line processing.
  • Batch and parallelize for performance with many items.

๐Ÿ‘‰ Continue to: Functions and Libraries