Циклы в Bash Full Linux

циклы в bash с примерами, объяснениями и задачами для практики. 📚

📌 Типы циклов в Bash

1. ЦИКЛ FOR — «ДЛЯ КАЖДОГО»

Синтаксис:

bash

for переменная in список_элементов
do
    команды
done

Пример 1: Простой перебор

bash

# Перебираем фрукты
for fruit in apple banana orange
do
    echo "Я люблю $fruit"
done

Вывод:

text

Я люблю apple
Я люблю banana
Я люблю orange

Пример 2: Перебор файлов

bash

# Создаем несколько файлов
touch file1.txt file2.txt "документ 3.txt"

# Перебираем все txt файлы
for file in *.txt
do
    echo "Найден файл: $file"
    wc -l "$file"  # считаем строки в файле
done

Пример 3: Цикл с диапазоном чисел

bash

# От 1 до 5
for i in {1..5}
do
    echo "Итерация номер $i"
done

# С шагом 2 (1, 3, 5, 7, 9)
for i in {1..10..2}
do
    echo "Нечетное: $i"
done

2. ЦИКЛ WHILE — «ПОКА УСЛОВИЕ ВЕРНО»

Синтаксис:

bash

while условие
do
    команды
done

Пример 1: Счетчик

bash

counter=1
while [ $counter -le 5 ]
do
    echo "Счет: $counter"
    counter=$((counter + 1))  # увеличиваем на 1
done

Пример 2: Чтение файла построчно

bash

# Создаем файл с именами
echo -e "Анна\nБорис\nМария\nИван" > names.txt

# Читаем файл
while read name
do
    echo "Привет, $name!"
done < names.txt

Пример 3: Бесконечный цикл с выходом по условию

bash

while true  # всегда истинно
do
    echo "Введите 'exit' для выхода:"
    read input
    if [ "$input" = "exit" ]; then
        echo "Выход из цикла!"
        break  # выход из цикла
    fi
    echo "Вы ввели: $input"
done

3. ЦИКЛ UNTIL — «ПОКА УСЛОВИЕ ЛОЖНО» (обратный while)

Пример:

bash

counter=10
until [ $counter -eq 0 ]  # пока не равно 0
do
    echo "Обратный отсчет: $counter"
    counter=$((counter - 1))
    sleep 1  # пауза 1 секунда
done
echo "Старт!"

🎯 ЦИКЛЫ С IF ВНУТРИ

Пример 1: Проверка файлов

bash

# Создаем разные файлы
echo "test" > normal.txt
echo "secret" > .hidden.txt
chmod 000 locked.txt  # файл без прав

for file in *
do
    if [ -f "$file" ]; then           # если это обычный файл
        if [[ "$file" == .* ]]; then  # если скрытый файл
            echo "Скрытый файл: $file"
        elif [ ! -r "$file" ]; then   # если нельзя читать
            echo "Заблокирован: $file"
        else
            echo "Обычный файл: $file"
            # можно что-то сделать с файлом
        fi
    fi
done

Пример 2: Классификация чисел

bash

for num in {1..20}
do
    if [ $((num % 2)) -eq 0 ] && [ $((num % 3)) -eq 0 ]; then
        echo "$num делится и на 2, и на 3"
    elif [ $((num % 2)) -eq 0 ]; then
        echo "$num четное"
    elif [ $((num % 3)) -eq 0 ]; then
        echo "$num делится на 3"
    else
        echo "$num простое число"
    fi
done

Пример 3: Мониторинг системы

bash

# Проверяем использование диска для каждого раздела
while true
do
    clear  # очищаем экран
    
    echo "=== МОНИТОРИНГ ДИСКОВ ==="
    echo "Время: $(date)"
    echo ""
    
    # df показывает использование диска
    df -h | while read line
    do
        # Пропускаем заголовок
        if [[ $line == Filesystem* ]]; then
            echo "$line"
            continue
        fi
        
        # Разбираем строку
        usage=$(echo $line | awk '{print $5}' | tr -d '%')
        mount=$(echo $line | awk '{print $6}')
        
        if [ $usage -gt 90 ]; then
            echo "⚠️  КРИТИЧЕСКИ: $mount заполнен на $usage%"
        elif [ $usage -gt 70 ]; then
            echo "⚠️  ВНИМАНИЕ: $mount заполнен на $usage%"
        else
            echo "✅ НОРМА: $mount заполнен на $usage%"
        fi
    done
    
    echo ""
    echo "Нажмите Ctrl+C для выхода"
    sleep 5  # ждем 5 секунд
done

🧠 ПРАКТИЧЕСКИЕ ЗАДАЧИ ДЛЯ BASH

Задача 1: Начинающий уровень

Создать скрипт, который:

  1. Создает 10 файлов с именами backup_1.txt до backup_10.txt
  2. В каждый файл записывает текущую дату
  3. Выводит имена только созданных файлов

<details> <summary>🔑 Решение</summary>

bash

#!/bin/bash

for i in {1..10}
do
    filename="backup_$i.txt"
    date > "$filename"
    echo "Создан файл: $filename"
done

echo "=== Все созданные файлы ==="
ls backup_*.txt

</details>

Задача 2: Средний уровень

Создать скрипт для очистки временных файлов:

  1. Найти все файлы старше 7 дней в папке /tmp
  2. Проверить размер каждого файла
  3. Удалить только файлы больше 100MB
  4. Вести лог удаленных файлов

<details> <summary>🔑 Решение</summary>

bash

#!/bin/bash

LOG_FILE="cleanup.log"
echo "Очистка начата: $(date)" >> "$LOG_FILE"

# Ищем файлы старше 7 дней
find /tmp -type f -mtime +7 | while read file
do
    # Получаем размер файла в байтах
    size=$(stat -c%s "$file" 2>/dev/null || echo "0")
    
    if [ $size -gt 104857600 ]; then  # 100MB в байтах
        echo "Удаляю: $file (размер: $size байт)" | tee -a "$LOG_FILE"
        rm -f "$file"
    fi
done

echo "Очистка завершена: $(date)" >> "$LOG_FILE"
echo "Лог сохранен в: $LOG_FILE"

</details>

Задача 3: Продвинутый уровень

Создать менеджер процессов:

  1. Показывать список всех запущенных процессов
  2. Предлагать пользователю выбрать PID для завершения
  3. Проверять, существует ли процесс
  4. Запрашивать подтверждение перед убийством
  5. Выйти по команде «exit»

<details> <summary>🔑 Решение</summary>

bash

#!/bin/bash

while true
do
    clear
    echo "=== МЕНЕДЖЕР ПРОЦЕССОВ ==="
    echo ""
    
    # Показываем топ-10 процессов по использованию памяти
    ps aux --sort=-%mem | head -11
    
    echo ""
    echo "Введите PID процесса для завершения (или 'exit' для выхода):"
    read input
    
    if [ "$input" = "exit" ]; then
        echo "Выход из программы"
        break
    fi
    
    # Проверяем, что ввели число
    if ! [[ "$input" =~ ^[0-9]+$ ]]; then
        echo "Ошибка: введите число!"
        sleep 2
        continue
    fi
    
    # Проверяем существование процесса
    if ps -p "$input" > /dev/null 2>&1; then
        # Показываем информацию о процессе
        echo "Процесс найден:"
        ps -p "$input" -o pid,user,cmd
        
        echo ""
        echo "Вы уверены, что хотите завершить процесс $input? (y/n)"
        read confirm
        
        if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
            kill "$input"
            echo "Процесс $input завершен"
            sleep 2
        else
            echo "Отмена"
            sleep 1
        fi
    else
        echo "Процесс с PID $input не найден!"
        sleep 2
    fi
done

</details>

🔧 ПОЛЕЗНЫЕ ШАБЛОНЫ ДЛЯ ЦИКЛОВ

Шаблон 1: Обработка аргументов скрипта

bash

#!/bin/bash
# Использование: ./script.sh file1.txt file2.txt ...

echo "Обработка $# файлов..."

for file in "$@"
do
    if [ ! -f "$file" ]; then
        echo "Ошибка: $file не существует"
        continue
    fi
    
    echo "Обрабатываю: $file"
    # ... действия с файлом ...
done

Шаблон 2: Резервное копирование с проверкой

bash

#!/bin/bash

BACKUP_DIR="/backup"
SOURCES=("/home/user/docs" "/var/www" "/etc")

for source_dir in "${SOURCES[@]}"
do
    if [ ! -d "$source_dir" ]; then
        echo "Пропускаю: $source_dir (не существует)"
        continue
    fi
    
    backup_file="$BACKUP_DIR/$(basename "$source_dir")_$(date +%Y%m%d).tar.gz"
    
    if tar -czf "$backup_file" "$source_dir" 2>/dev/null; then
        echo "✅ Успешно: $source_dir -> $backup_file"
    else
        echo "❌ Ошибка при архивировании $source_dir"
    fi
done

Шаблон 3: Мониторинг сервисов

bash

#!/bin/bash

SERVICES=("nginx" "mysql" "ssh")

while true
do
    echo "=== Проверка сервисов ==="
    echo "Время: $(date)"
    
    all_ok=true
    
    for service in "${SERVICES[@]}"
    do
        if systemctl is-active --quiet "$service"; then
            echo "✅ $service работает"
        else
            echo "❌ $service НЕ РАБОТАЕТ!"
            all_ok=false
        fi
    done
    
    if $all_ok; then
        echo "Все сервисы работают нормально"
    else
        echo "Есть проблемы с сервисами!"
        # Можно добавить отправку email или уведомление
    fi
    
    echo ""
    sleep 60  # проверка каждую минуту
done

📝 ЧЕК-ЛИСТ ДЛЯ НАПИСАНИЯ ЦИКЛОВ:

  1. ✅ Всегда используйте "$переменная" в кавычках
  2. ✅ Используйте [[ ]] для строковых сравнений
  3. ✅ Для арифметики используйте $((выражение))
  4. ✅ Используйте continue для пропуска итерации
  5. ✅ Используйте break для выхода из цикла
  6. ✅ Проверяйте существование файлов перед работой с ними
  7. ✅ Добавляйте комментарии для сложных условий
  8. ✅ Тестируйте скрипт на тестовых данных

🎓 ДОПОЛНИТЕЛЬНЫЕ ЗАДАЧИ ДЛЯ ПРАКТИКИ:

Задача 4: Напишите скрипт, который генерирует таблицу умножения 10×10

Задача 5: Создайте скрипт для поиска дубликатов файлов по размеру и имени

Задача 6: Напишите скрипт, который мониторит изменение файлов в директории и выводит уведомления

Задача 7: Создайте простой калькулятор с меню (+, -, *, /) в цикле while

Попробуйте решить эти задачи самостоятельно! Если будут вопросы или нужны подсказки — обращайтесь!

Оставьте комментарий