Bash — Loops
If you like this project, consider supporting me on Buy Me a Coffee ☕️
tags:
- text-parsing
- linux
-
sysadmin
Bash Loops — built-in shell constructs (
for,while,until) for iterating over files, numbers, arrays, and command output. These are not standalone programs but fundamental parts of Bash (Bourne-Again SHell), the default shell on most Linux systems. Loops are essential for scripting automation, batch processing, retry logic, and monitoring. For complex orchestration, consider dedicated tools likeansibleorxargs --parallel.
🔄 FOR Loops
Over Files
for f in *.log; do echo "$f"; done # Iterate .log files / Перебрать .log файлы
for f in *.{yml,yaml}; do echo "$f"; done # Multiple extensions / Несколько расширений
for f in /var/log/*.log; do : > "$f"; done # Truncate all logs / Очистить все логи
for f in $(find . -name "*.txt"); do echo "$f"; done # With find / С find
for f in *.conf; do cp "$f" "$f.bak"; done # Backup all configs / Бэкап всех конфигов
Over Numbers
for i in {1..5}; do echo $i; done # Range 1-5 / Диапазон 1-5
for i in {1..10..2}; do echo $i; done # Step by 2 / Шаг 2
for i in {10..1}; do echo $i; done # Reverse / Обратный порядок
for ((i=1; i<=5; i++)); do echo $i; done # C-style loop / Цикл в стиле C
for ((i=0; i<10; i+=2)); do echo $i; done # C-style with step / С шагом
Over Arrays
arr=("apple" "banana" "cherry")
for item in "${arr[@]}"; do echo "$item"; done # Iterate array / Перебрать массив
for i in "${!arr[@]}"; do echo "$i: ${arr[$i]}"; done # With indices / С индексами
Over Command Output
for user in $(cut -d: -f1 /etc/passwd); do echo "$user"; done # All users / Все пользователи
for ip in $(cat ips.txt); do ping -c1 "$ip"; done # Ping all IPs / Пинговать все IP
for pod in $(kubectl get pods -o name); do kubectl describe "$pod"; done # K8s pods / Поды Kubernetes
⏳ WHILE Loops
Basic While
i=1
while [ $i -le 5 ]; do
echo $i
((i++))
done # Counter 1-5 / Счётчик 1-5
Read from File
while read -r line; do
echo "$line"
done < file.txt # Read file lines / Читать построчно
Infinite Loops
while :; do
date
sleep 5
done # Tick every 5s / Каждые 5 секунд
while true; do
echo "Running..."
sleep 10
done # Alternative infinite / Альтернативный бесконечный
Conditional While
while pgrep -x "nginx" > /dev/null; do
echo "Nginx running"
sleep 5
done # While process exists / Пока процесс существует
while ! ping -c1 8.8.8.8 &>/dev/null; do
echo "Waiting for network..."
sleep 2
done # Wait for network / Ждать сети
🔁 UNTIL Loops
Basic Until
i=1
until [ $i -gt 5 ]; do
echo $i
((i++))
done # Run until condition true / Пока условие ЛОЖНО
Wait for Condition
until curl -sf http://localhost:8080/health > /dev/null; do
echo "Waiting for service..."
sleep 2
done # Wait for service / Ждать сервис
until [ -f /tmp/ready ]; do
echo "Waiting for file..."
sleep 1
done # Wait for file / Ждать файл
🎮 Loop Control
Break
for i in {1..10}; do
if [ $i -eq 5 ]; then
break
fi
echo $i
done # Exit loop at 5 / Выход на 5
Continue
for i in {1..10}; do
if [ $((i % 2)) -eq 0 ]; then
continue
fi
echo $i
done # Skip even numbers / Пропустить чётные
Nested Loops
for i in {1..3}; do
for j in {1..3}; do
echo "$i,$j"
done
done # Nested iteration / Вложенный перебор
📖 Reading Files
Read Lines
while IFS= read -r line; do
echo "$line"
done < file.txt # Preserve whitespace / Сохранить пробелы
Read CSV
while IFS=',' read -r col1 col2 col3; do
echo "Col1: $col1, Col2: $col2"
done < data.csv # Parse CSV / Парсить CSV
Process Substitution
while IFS= read -r f; do
echo "$f"
done < <(ls -1) # No subshell variable loss / Без потери переменных
Read with Timeout
while read -t 5 -r line; do
echo "$line"
done < <(some_command) # 5s timeout / Таймаут 5с
🌟 Real-World Examples
System Administration
# Rotate logs
for log in /var/log/app/*.log; do
mv "$log" "$log.old"
touch "$log"
done
# Monitor services
while :; do
if ! systemctl is-active --quiet nginx; then
echo "Nginx down, restarting..."
systemctl restart nginx
fi
sleep 60
done
# Cleanup old files
for f in $(find /tmp -name "*.tmp" -mtime +7); do
echo "Deleting $f"
rm "$f"
done
Network Operations
# Ping sweep
for i in {1..254}; do
{
ip="192.168.1.$i"
ping -c1 -W1 "$ip" &>/dev/null && echo "$ip is up"
} &
done
wait
# Port scan
for port in {20..30}; do
timeout 1 bash -c "echo > /dev/tcp/<HOST>/$port" 2>/dev/null && echo "Port $port open"
done
# Check URLs
while IFS= read -r url; do
status=$(curl -o /dev/null -s -w "%{http_code}" "$url")
echo "$url: $status"
done < urls.txt
File Processing
# Batch rename
for f in *.jpeg; do
mv "$f" "${f%.jpeg}.jpg"
done
# Convert images
for img in *.png; do
convert "$img" "${img%.png}.webp"
done
# Extract archives
for archive in *.tar.gz; do
tar -xzf "$archive" -C /dest/
done
Database Operations
# Backup all databases
for db in $(mysql -Ne "SHOW DATABASES" | grep -v "information_schema\|performance_schema\|mysql"); do
mysqldump "$db" | gzip > "/backup/${db}-$(date +%Y%m%d).sql.gz"
done
# Check DB connections
while IFS= read -r host; do
mysql -h "$host" -e "SELECT 1" &>/dev/null && echo "$host: OK" || echo "$host: FAIL"
done < db_hosts.txt
Kubernetes / Docker
[!CAUTION] Deleting pods and containers is destructive. Make sure you are targeting the correct namespace/resources. Удаление подов и контейнеров — деструктивная операция. Убедитесь, что вы работаете с нужным namespace/ресурсами.
# Restart all pods
for pod in $(kubectl get pods -o name -n <NAMESPACE>); do
kubectl delete "$pod" -n <NAMESPACE>
done
# Cleanup old containers
for container in $(docker ps -aq); do
docker rm -f "$container"
done
# Check pod status
while :; do
kubectl get pods -o wide
sleep 10
done
Parallel Processing
# Process files in parallel
for f in *.log; do
{
gzip "$f"
echo "$f compressed"
} &
done
wait # Wait for all background jobs / Ждать все фоновые задачи
# Limited parallelism
max_jobs=4
for f in *.txt; do
while [ $(jobs -r | wc -l) -ge $max_jobs ]; do
sleep 0.1
done
{
process_file "$f"
} &
done
wait
Monitoring & Alerting
# Watch disk space
while :; do
usage=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$usage" -gt 90 ]; then
echo "Disk usage critical: ${usage}%"
fi
sleep 300
done
# Monitor log for errors
tail -f /var/log/app.log | while read -r line; do
if echo "$line" | grep -q "ERROR"; then
echo "Error detected: $line"
fi
done
Advanced Patterns
# Counter with timeout
timeout=10
counter=0
while [ $counter -lt $timeout ]; do
if check_condition; then
echo "Success!"
break
fi
((counter++))
sleep 1
done
# Retry logic
max_retries=3
retry=0
until some_command || [ $retry -eq $max_retries ]; do
((retry++))
echo "Retry $retry/$max_retries..."
sleep 5
done
# Interactive menu
options=("Start" "Stop" "Restart" "Exit")
while :; do
for i in "${!options[@]}"; do
echo "$((i+1)). ${options[$i]}"
done
read -p "Select option: " choice
case $choice in
4) break ;;
*) echo "Processing ${options[$((choice-1))]}" ;;
esac
done
📚 Documentation
- Bash Reference Manual — Looping Constructs
- Bash Reference Manual (full)
- Advanced Bash-Scripting Guide — Loops
help for/help while/help until(Bash built-in help)