Скрипты для обрезания логов Bash
Вашему вниманию предлагаю скрипты для обрезания логов Bash. Первый скрипт срезает файлы *.log у которых размер кол-во строк более 10000 (MAX_LINES). Я расставил комментарии и вы сможете понять суть. Запускать скрипт необходимо один раз в неделю по крону. Лучше запускать в полночь. Скрипт не записывает вывод в файл вам необходимо перенаправить вывод в файл >> file.log. Можете смело запускать. Я запускал не раз и сервер не падал. Этот скрипт хорош для фреймворков. Часто логи от работающих фреймворков достигаю размер свыше 10 Гб и могут заполнить свободно место HDD.
#!/bin/bash
# Скрипт для обрезки больших логов: если строк > MAX_LINES, оставляем только последние KEEP_LINES
# ================== НАСТРОЙКИ ==================
MAX_LINES=10000 # Если строк больше этого значения — обрезаем
KEEP_LINES=500 # Сколько последних строк оставлять
# Массив с директориями для поиска
SEARCH_ROOTS=(
"/var/log"
"/home"
"/opt"
"/usr/local"
"/var/www"
# "/tmp"
)
# ===============================================
TEMP_FILE="/tmp/log_truncate_line_$$.tmp" # Временный файл с уникальным PID
echo "Запуск обрезки логов"
echo "Условие: если строк > $MAX_LINES — оставляем последние $KEEP_LINES строк"
echo "Поиск в: $SEARCH_ROOT"
echo "------------------------------------------------------------"
count=0 # Всего найдено .log файлов
checked=0 # Файлов, где посчитали строки
truncated=0 # Файлов, которые обрезали
# Ищем все .log файлы
find "${SEARCH_ROOTS[@]}" -type f -name "*.log" 2>/dev/null | while read -r logfile; do
((count++))
# Проверяем права на чтение и запись
if [[ ! -r "$logfile" || ! -w "$logfile" ]]; then
echo "ПРОПУСК (нет прав): $logfile"
continue
fi
# Считаем строки
total_lines=$(wc -l < "$logfile" 2>/dev/null)
((checked++))
# Если строк ≤ MAX_LINES — пропускаем
if [[ $total_lines -le $MAX_LINES ]]; then
echo "ОК ($total_lines ≤ $MAX_LINES строк): $logfile"
continue
fi
# Обрезаем: оставляем только последние KEEP_LINES строк
tail -n "$KEEP_LINES" "$logfile" > "$TEMP_FILE"
if [[ $? -ne 0 ]]; then
echo "ОШИБКА при создании временного файла: $logfile"
continue
fi
# Перезаписываем оригинал
mv "$TEMP_FILE" "$logfile"
removed=$((total_lines - KEEP_LINES))
((truncated++))
echo "ОБРЕЗАНО ($total_lines → $KEEP_LINES, удалено $removed строк): $logfile"
done
# Очистка временного файла на случай прерывания
[[ -f "$TEMP_FILE" ]] && rm -f "$TEMP_FILE"
echo "------------------------------------------------------------"
echo "Готово!"
echo "Найдено .log файлов: $count"
echo "Проверено на количество строк: $checked"
echo "Обрезано файлов: $truncated" Второй скрипт похож на первый. Скрипт срезает файлы *.log у которых размер больше 1 Мб (MAX_SIZE_MB). Этот скрипт в разы шустрее первого, но он не учитывает кол-во строк. Тут учитывается размер файла.
#!/bin/bash
# Скрипт для обрезки больших логов: если размер > MAX_SIZE МБ, оставляем только последние KEEP_LINES строк
# ================== НАСТРОЙКИ ==================
MAX_SIZE_MB=10 # Если размер > этого значения (в МБ) — обрезаем
KEEP_LINES=500 # Сколько последних строк оставлять
# Массив с директориями для поиска
SEARCH_ROOTS=(
"/var/log"
"/home"
"/opt"
"/usr/local"
"/var/www"
# "/tmp"
)
# ===============================================
TEMP_FILE="/tmp/log_truncate_size_$$.tmp"
echo "Запуск обрезки логов"
echo "Условие: если размер > $MAX_SIZE_MB МБ — оставляем последние $KEEP_LINES строк"
echo "Поиск в: ${SEARCH_ROOTS[*]}"
echo "------------------------------------------------------------"
count=0 # Всего найдено .log файлов
checked=0 # Файлов, где посчитали размер
truncated=0 # Файлов, которые обрезали
# Ищем все .log файлы
find "${SEARCH_ROOTS[@]}" -type f -name "*.log" 2>/dev/null | while read -r logfile; do
((count++))
# Проверяем права на чтение и запись
if [[ ! -r "$logfile" || ! -w "$logfile" ]]; then
echo "ПРОПУСК (нет прав): $logfile"
continue
fi
# Получаем размер в байтах, затем переводим в МБ (целочисленно)
size_bytes=$(stat -c %s "$logfile" 2>/dev/null || echo 0)
size_mb=$(( size_bytes / 1024 / 1024 ))
((checked++))
# Если размер файла ≤ $MAX_SIZE_MB — пропускаем
if [[ $size_mb -le $MAX_SIZE_MB ]]; then
echo "ОК (${size_mb} МБ ≤ $MAX_SIZE_MB МБ): $logfile"
continue
fi
# Обрезаем: оставляем только последние KEEP_LINES строк
tail -n "$KEEP_LINES" "$logfile" > "$TEMP_FILE"
if [[ $? -ne 0 ]]; then
echo "ОШИБКА при создании временного файла: $logfile"
continue
fi
# Перезаписываем оригинал
mv "$TEMP_FILE" "$logfile"
((truncated++))
echo "ОБРЕЗАНО (${size_mb} МБ → ~меньше, оставлено $KEEP_LINES строк): $logfile"
done
# Очистка временного файла на случай прерывания
[[ -f "$TEMP_FILE" ]] && rm -f "$TEMP_FILE"
echo "------------------------------------------------------------"
echo "Готово!"
echo "Найдено .log файлов: $count"
echo "Проверено на размер: $checked"
echo "Обрезано файлов: $truncated"