While Loops

For loops iterate over lists. While loops repeat as long as a condition is true. Different tools for different jobs.

Basic While Loop

hljs bash
#!/bin/bash

count=1

while [[ $count -le 5 ]]; do
    echo "Count: $count"
    ((count++))
done
Terminal
$./count.sh
Count: 1 Count: 2 Count: 3 Count: 4 Count: 5

Infinite Loops

Forget to increment the counter? Infinite loop. Always ensure the condition eventually becomes false.

Read File Line by Line

hljs bash
#!/bin/bash

while read line; do
    echo "Line: $line"
done < file.txt

This is the idiomatic way to process files. Better than for line in $(cat file) which breaks on spaces.

Preserve Whitespace

hljs bash
#!/bin/bash

while IFS= read -r line; do
    echo "$line"
done < file.txt
  • IFS= preserves leading/trailing whitespace
  • -r prevents backslash interpretation

Wait for Condition

hljs bash
#!/bin/bash
# Wait for a file to appear

echo "Waiting for data.txt..."

while [[ ! -f "data.txt" ]]; do
    sleep 1
done

echo "File found!"

Process Command Output

hljs bash
#!/bin/bash

ps aux | while read line; do
    echo "$line" | grep nginx
done

# Or more simply:
while read line; do
    if [[ "$line" == *nginx* ]]; then
        echo "$line"
    fi
done < <(ps aux)

Until Loop (Opposite of While)

hljs bash
#!/bin/bash

count=1

until [[ $count -gt 5 ]]; do
    echo "Count: $count"
    ((count++))
done

until runs while condition is false (opposite of while).

Infinite Loop (Intentional)

hljs bash
#!/bin/bash
# Simple service loop

while true; do
    echo "Running task..."
    ./do_work.sh
    sleep 60
done

Or:

hljs bash
while :; do
    # : is always true
    echo "Forever..."
    sleep 1
done

Use Ctrl+C to stop.

Loop Control

hljs bash
#!/bin/bash

count=0

while true; do
    ((count++))

    if [[ $count -eq 3 ]]; then
        continue  # skip this iteration
    fi

    if [[ $count -eq 5 ]]; then
        break  # exit loop
    fi

    echo "Count: $count"
done

# Output: 1 2 4

Practical Examples

Retry Until Success

hljs bash
#!/bin/bash

max_attempts=5
attempt=1

while [[ $attempt -le $max_attempts ]]; do
    echo "Attempt $attempt..."

    if curl -s http://example.com > /dev/null; then
        echo "Success!"
        break
    fi

    ((attempt++))
    sleep 2
done

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

Monitor Log File

hljs bash
#!/bin/bash
# Watch for errors in real-time

tail -f /var/log/app.log | while read line; do
    if [[ "$line" == *ERROR* ]]; then
        echo "ALERT: $line"
        # send notification
    fi
done

Interactive Menu

hljs bash
#!/bin/bash

while true; do
    echo ""
    echo "1) Start"
    echo "2) Stop"
    echo "3) Status"
    echo "4) Exit"

    read -p "Choice: " choice

    case $choice in
        1) echo "Starting..." ;;
        2) echo "Stopping..." ;;
        3) echo "Status: OK" ;;
        4) break ;;
        *) echo "Invalid option" ;;
    esac
done
Knowledge Check

What's the safest way to read a file line by line?

Quick Reference

SyntaxPurpose
while [[ cond ]]; do ... doneLoop while true
until [[ cond ]]; do ... doneLoop while false
while read line; do ... done < fileRead file lines
while true; do ... doneInfinite loop
breakExit loop
continueSkip to next iteration

Key Takeaways

  • While loops repeat as long as condition is true
  • Perfect for file processing with while read
  • Use IFS= read -r for preserving exact line content
  • until is the opposite of while
  • while true for intentional infinite loops
  • Always ensure loops can exit (avoid infinite loops)

Next: script arguments - make scripts flexible.