training-web.ruГлавнаяКатегорииО насКарта сайтаПоискТёмная тема

Категории

Скрипты для обрезания логов Bash

Создано: 24 декабря 2025Автор: Егор Астапов107 просмотровСложность: легкий

Вашему вниманию предлагаю скрипты для обрезания логов 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"

Комментарии

реклама