✅ Решения — Продолжение работы со скриптами

К оглавлению урока

⚡ Ключевые конструкции решений

# Задача 1: числовое сравнение
if [ "$disk_usage" -gt "$threshold" ]; then ...

# Задача 2: системный отчёт
os_version=$(cat /etc/os-release | grep "PRETTY_NAME" | cut -d '"' -f 2)
user_count=$(who | wc -l)

# Задача 3: cron + find -delete
find "$backup_location" -maxdepth 1 -type f -name "*.tar.gz" -mtime +21 -delete

# Задача 4: анализ логов
grep -E -r "$error_patterns" "$log_directory" | sort | uniq -c | sort -nr

Решение 1 — Мониторинг дискового пространства

# disk_monitor.sh

#!/bin/bash
# Пороговое значение для занятого дискового пространства (в процентах)
threshold=70

# Получаем процент занятого дискового пространства корневого раздела
disk_usage=$(df / | awk '{print $5}' | sed 's/%//')

if [ "$disk_usage" -gt "$threshold" ]; then
    echo "Disk usage exceeds $threshold% threshold. Searching for largest directories and files..."
    echo "Largest directories and files:"
    du -ah / | sort -rh | head -n 10
else
    echo "Disk usage on the root partition is $disk_usage% (within threshold of $threshold%)."
fi

Пояснения

  • df / | awk '{print $5}' — строка с Use% содержит несколько строк; нужна вторая (данные, не заголовок). На практике awk вернёт оба значения — можно уточнить через tail -1: df / | tail -1 | awk '{print $5}'
  • sed 's/%//' — заменяет % на пустую строку (одно вхождение)
  • -gt — greater than (больше чем). Числовые операторы в bash: -eq, -ne, -lt, -le, -gt, -ge
  • du -ah / — размер всех файлов и директорий рекурсивно; -a включает файлы, не только директории

Решение 2 — Системный отчёт

# system_report.sh

#!/bin/bash
# Версия операционной системы
os_version=$(cat /etc/os-release | grep "PRETTY_NAME" | cut -d '"' -f 2)

# Дата и время
current_date=$(date "+%Y-%m-%d")
current_time=$(date "+%H:%M:%S")

# Время работы системы
uptime_info=$(uptime -p)

# Загруженность системы
system_load=$(uptime | awk -F'[a-z]:' '{ print $2 }')

# Занятое дисковое пространство
disk_usage=$(df / | awk '{print $5}' | sed 's/%//')

# Топ процессы по использованию памяти
top_processes=$(ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -n 6)

# Количество процессов
process_count=$(ps -ef | wc -l)

# Количество пользователей
user_count=$(who | wc -l)

echo "System Report"
echo "OS Version: $os_version"
echo "Date: $current_date"
echo "Time: $current_time"
echo "System Uptime: $uptime_info"
echo "System Load: $system_load"
echo "Disk Usage: $disk_usage%"
echo "Top processes by memory usage:"
echo "$top_processes"
echo "Number of processes: $process_count"
echo "Number of logged-in users: $user_count"

Пояснения

  • cut -d '"' -f 2 — разделитель — кавычка "; 2-е поле = значение между кавычками (например Ubuntu 22.04.1 LTS)
  • uptime | awk -F'[a-z]:' '{ print $2 }' — регулярный разделитель; вся строка после load average: — нагрузка
  • ps -eo — вывести только указанные поля (o = output format)

Решение 3 — Cron-бекап

# backup_script.sh

#!/bin/bash
backup_dirs=("/opt" "/home/ec2-user")
backup_location="/backup"
max_backup_count=3

mkdir -p "$backup_location"

for dir in "${backup_dirs[@]}"; do
    backup_file="$backup_location/$(basename "$dir")_backup_$(date +%Y-%m-%d).tar.gz"
    tar -czf "$backup_file" "$dir"
done

# -mtime +21: файлы, не менявшиеся более 21 дня
find "$backup_location" -maxdepth 1 -type f -name "*.tar.gz" -mtime +21 -delete

Настройка cron

crontab -e
# Добавить:
0 2 * * 0 /home/ec2-user/backup_script.sh >> /home/ec2-user/backup.log 2>&1

Пояснения

  • "${backup_dirs[@]}" — перебор всех элементов массива с правильной обработкой пробелов в именах
  • basename "$dir" — имя директории без пути (например: opt, ec2-user)
  • -maxdepth 1 — искать только в самой директории, не рекурсивно

Решение 4 — Мониторинг логов

# log_monitor.sh

#!/bin/bash
log_directory="/var/log"
report_file="/tmp/error_report.txt"
error_patterns="(error|Error|ERROR|warning|Warning|WARNING)"

grep -E -r "$error_patterns" "$log_directory" \
    | awk -F ':' '{print $2}' \
    | sort \
    | uniq -c \
    | sort -nr > "$report_file"

echo "Error report for logs in $log_directory:"
cat "$report_file"

echo ""
echo "Top 5 most frequent errors:"
head -n 5 "$report_file"

Пояснения

  • grep -E — ERE (Extended Regular Expressions); нужно для (error|Error|ERROR)
  • awk -F ':' '{print $2}' — разделитель :; $2 = текст после первого двоеточия (сообщение ошибки без имени файла)
  • sort | uniq -cuniq -c требует отсортированные данные; без sort подсчёт будет неверным
  • sort -nr — числовая (-n) и обратная (-r) сортировка