циклы в 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: Начинающий уровень
Создать скрипт, который:
- Создает 10 файлов с именами
backup_1.txtдоbackup_10.txt - В каждый файл записывает текущую дату
- Выводит имена только созданных файлов
<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: Средний уровень
Создать скрипт для очистки временных файлов:
- Найти все файлы старше 7 дней в папке
/tmp - Проверить размер каждого файла
- Удалить только файлы больше 100MB
- Вести лог удаленных файлов
<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: Продвинутый уровень
Создать менеджер процессов:
- Показывать список всех запущенных процессов
- Предлагать пользователю выбрать PID для завершения
- Проверять, существует ли процесс
- Запрашивать подтверждение перед убийством
- Выйти по команде «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
📝 ЧЕК-ЛИСТ ДЛЯ НАПИСАНИЯ ЦИКЛОВ:
- ✅ Всегда используйте
"$переменная"в кавычках - ✅ Используйте
[[ ]]для строковых сравнений - ✅ Для арифметики используйте
$((выражение)) - ✅ Используйте
continueдля пропуска итерации - ✅ Используйте
breakдля выхода из цикла - ✅ Проверяйте существование файлов перед работой с ними
- ✅ Добавляйте комментарии для сложных условий
- ✅ Тестируйте скрипт на тестовых данных
🎓 ДОПОЛНИТЕЛЬНЫЕ ЗАДАЧИ ДЛЯ ПРАКТИКИ:
Задача 4: Напишите скрипт, который генерирует таблицу умножения 10×10
Задача 5: Создайте скрипт для поиска дубликатов файлов по размеру и имени
Задача 6: Напишите скрипт, который мониторит изменение файлов в директории и выводит уведомления
Задача 7: Создайте простой калькулятор с меню (+, -, *, /) в цикле while
Попробуйте решить эти задачи самостоятельно! Если будут вопросы или нужны подсказки — обращайтесь!