while Loop
Execute commands repeatedly while a condition is true
Syntax:
while [ condition ]; do commands; done
Note: The while loop is a fundamental control structure in shell scripting that executes a block of commands repeatedly as long as the specified condition remains true.
Description
The while loop is a control flow statement that allows code to be executed repeatedly based on a given boolean condition. The loop continues to execute the block of commands as long as the condition evaluates to true. It's essential for automation, data processing, and creating interactive scripts.
Basic Syntax Forms
Standard while loop:
# Basic syntax
while [ condition ]
do
commands
done
# One-line syntax
while [ condition ]; do commands; done
# Alternative test syntax
while test condition; do commands; done
Common Conditions
| Condition Type | Syntax | Description |
|---|---|---|
| Numeric comparison | [ $n -lt 10 ] |
Less than, greater than, equal |
| String comparison | [ "$str" = "value" ] |
String equality, inequality |
| File tests | [ -f file ] |
File existence, permissions |
| Command success | command |
Exit status of command |
| Always true | true |
Infinite loop |
Basic Examples
Simple counter loop:
#!/bin/bash
# Count from 1 to 5
counter=1
while [ $counter -le 5 ]
do
echo "Count: $counter"
counter=$((counter + 1))
done
Reading user input:
#!/bin/bash
# Keep asking until user enters 'quit'
while true
do
read -p "Enter command (quit to exit): " input
if [ "$input" = "quit" ]; then
break
fi
echo "You entered: $input"
done
File Processing
Reading file line by line:
#!/bin/bash
# Read file line by line
while IFS= read -r line
do
echo "Processing: $line"
done < input.txt
# Alternative with pipe
cat input.txt | while read line
do
echo "Line: $line"
done
Processing files in directory:
#!/bin/bash
# Process all .txt files
find . -name "*.txt" | while read filename
do
echo "Processing file: $filename"
wc -l "$filename"
done
System Monitoring
Monitor system resources:
#!/bin/bash
# Monitor disk usage
while true
do
usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $usage -gt 80 ]; then
echo "Warning: Disk usage is ${usage}%"
fi
sleep 60
done
Wait for service to start:
#!/bin/bash
# Wait for service to be ready
while ! nc -z localhost 8080
do
echo "Waiting for service to start..."
sleep 2
done
echo "Service is ready!"
Menu Systems
Interactive menu:
#!/bin/bash
while true
do
echo "=== Main Menu ==="
echo "1. List files"
echo "2. Show date"
echo "3. Show users"
echo "4. Exit"
read -p "Choose option: " choice
case $choice in
1) ls -la ;;
2) date ;;
3) who ;;
4) echo "Goodbye!"; break ;;
*) echo "Invalid option" ;;
esac
echo
done
Network Operations
Ping monitoring:
#!/bin/bash
# Monitor network connectivity
host="google.com"
while true
do
if ping -c 1 $host > /dev/null 2>&1; then
echo "$(date): $host is reachable"
else
echo "$(date): $host is unreachable"
fi
sleep 30
done
Data Processing
Process CSV data:
#!/bin/bash
# Process CSV file
while IFS=',' read -r name age city
do
echo "Name: $name, Age: $age, City: $city"
done < data.csv
Log file monitoring:
#!/bin/bash
# Monitor log file for errors
tail -f /var/log/application.log | while read line
do
if echo "$line" | grep -q "ERROR"; then
echo "Error detected: $line"
# Send alert or take action
fi
done
Loop Control
Break and continue:
#!/bin/bash
counter=0
while [ $counter -lt 10 ]
do
counter=$((counter + 1))
# Skip even numbers
if [ $((counter % 2)) -eq 0 ]; then
continue
fi
# Break at 7
if [ $counter -eq 7 ]; then
break
fi
echo "Odd number: $counter"
done
Infinite Loops
Different ways to create infinite loops:
# Using true
while true
do
commands
done
# Using :
while :
do
commands
done
# Using numeric condition
while [ 1 -eq 1 ]
do
commands
done
Error Handling
Retry mechanism:
#!/bin/bash
# Retry failed operations
max_attempts=3
attempt=0
while [ $attempt -lt $max_attempts ]
do
attempt=$((attempt + 1))
echo "Attempt $attempt of $max_attempts"
if command_that_might_fail; then
echo "Success!"
break
else
echo "Failed, retrying..."
sleep 2
fi
done
if [ $attempt -eq $max_attempts ]; then
echo "All attempts failed"
exit 1
fi
Advanced Examples
Backup script with rotation:
#!/bin/bash
# Backup with rotation
backup_dir="/backups"
max_backups=5
while [ $(ls -1 $backup_dir | wc -l) -gt $max_backups ]
do
oldest=$(ls -t $backup_dir | tail -1)
echo "Removing old backup: $oldest"
rm -rf "$backup_dir/$oldest"
done
# Create new backup
tar -czf "$backup_dir/backup_$(date +%Y%m%d_%H%M%S).tar.gz" /data
Process queue:
#!/bin/bash
# Process job queue
queue_file="/tmp/job_queue"
while [ -f "$queue_file" ] && [ -s "$queue_file" ]
do
# Get first job from queue
job=$(head -1 "$queue_file")
# Remove job from queue
sed -i '1d' "$queue_file"
echo "Processing job: $job"
# Process the job
eval "$job"
sleep 1
done
Performance Considerations
Optimizing while loops:
# Avoid expensive operations in condition
# Bad
while [ $(expensive_command) -eq 1 ]
do
commands
done
# Good
result=$(expensive_command)
while [ $result -eq 1 ]
do
commands
result=$(expensive_command)
done
# Use built-in tests when possible
# Faster: [ $n -lt 10 ]
# Slower: [ $(expr $n \< 10) -eq 1 ]
Common Pitfalls
Avoid these common mistakes:
- Infinite loops without break conditions
- Not updating loop variables
- Incorrect condition syntax
- Missing quotes around variables
- Not handling empty input properly
Debugging While Loops
Debug techniques:
# Add debug output
while [ $counter -lt 10 ]
do
echo "DEBUG: counter=$counter" >&2
# Your commands here
counter=$((counter + 1))
done
# Use set -x for tracing
set -x
while [ condition ]
do
commands
done
set +x
Common Use Cases
- File processing: Reading and processing files line by line
- System monitoring: Continuous monitoring of system resources
- User interaction: Creating interactive menus and prompts
- Data processing: Processing streams of data
- Service monitoring: Waiting for services to start or respond
- Backup automation: Automated backup and cleanup tasks
- Network monitoring: Checking connectivity and services
- Log processing: Real-time log analysis and alerting