Автоматизация удаления старых файлов с помощью systemd таймеров

«Чистить логи вручную, это рутина. Но рутина превращается в проблему, когда свободное место на диске исчезает без видимых причин, а сервисы начинают падать. Автоматизация через systemd таймеры или cron позволяет передать эту работу системе, чтобы освободить место и собственное время для реальных задач.»

Почему место на диске исчезает

В любой активной системе — сервер, хранилище или рабочая машина — файлы растут сами по себе. Это побочный продукт работы программ, а не ваши документы.

Основные потребители места:

  • Журналы событий (логи). Каждая служба, демон или приложение записывает свои действия. Веб-серверы, базы данных и системы мониторинга генерируют их постоянно.
  • Временные файлы. Процессы создают их для промежуточных расчётов, загрузок или установок, но не всегда удаляют.
  • Кэши приложений. Данные хранятся для ускорения работы, но их объём может выйти за пределы полезного.
  • Автоматические резервные копии. Если настроить создание, но не настроить ротацию (удаление старых), они заполнят всё пространство.

Проблема становится заметной, когда система начинает тормозить, программы падают с ошибками «no space left on device», или в мониторинге появляются тревожные показатели загрузки диска.

Ручная чистка против автоматизации

Ручная чистка, это разовое действие: найти объёмные файлы через du или ncdu, оценить, удалить. Проблема в повторяемости. Вы сделаете это сегодня, освободите место, но через несколько недель ситуация вернётся. Повседневные задачи и забывчивость приводят к тому, что чистка откладывается до критического момента.

Автоматизация превращает разовое действие в правило системы. Вы создаёте задачу (скрипт и планировщик) один раз, и она выполняется по расписанию — ежедневно, еженедельно, ежемесячно. Место освобождается регулярно, без вашего участия. Это переход от реактивного управления («решение проблемы») к проактивному («предотвращение проблемы»).

Systemd таймеры как системный диспетчер

Классический cron продолжает работать, но в современных дистрибутивах часто используется systemd. Помимо управления службами, он включает встроенный планировщик задач — таймеры (timers). Это юниты systemd, которые запускают другие юниты (например, службы или скрипты) по времени.

Преимущества systemd таймеров перед cron:

  • Интеграция с журналированием. Все запуски и результаты записываются в центральную систему журналирования journald. Статус задачи можно проверить через journalctl -u your-timer-name.
  • Гибкое расписание. Можно настроить запуск относительно времени последнего выполнения, что полезно для задач, которые не должны копиться при пропуске.
  • Зависимость от других служб. Можно гарантировать, что задача по чистке запустится только после старта системы или сетевого подключения.

Для создания задачи нужны два файла: .service (что делать) и .timer (когда делать). Они размещаются в /etc/systemd/system/.

Создание скрипта для безопасного удаления

Основой автоматизации является скрипт, который находит и удаляет старые файлы. Простое rm -rf /var/log/* разрушит систему. Нужен избирательный и безопасный подход.

Ключевые принципы:

  1. Критерий отбора. Чаще всего это возраст файла. Утилита find отбирает файлы по времени модификации (-mtime).
  2. Тестирование перед удалением. Всегда сначала используйте команду find с флагом -print, чтобы убедиться, что она находит нужные файлы. С опцией -delete или -exec нужно быть крайне осторожным.
  3. Сохранять актуальные файлы. Не трогать файлы, которые менялись в последние N дней.
  4. Очистка по размеру. Иногда полезно удалять не по времени, а по размеру каталога, если он превышает лимит.

Пример скрипта на bash для очистки старых логов веб-сервера nginx:

#!/bin/bash
# Скрипт для ротации логов nginx: удаляет файлы старше 30 дней.
LOG_DIR="/var/log/nginx"
RETENTION_DAYS=30

# Находим и удаляем файлы .log и .gz старше указанного количества дней.
find "$LOG_DIR" -type f ( -name "*.log" -o -name "*.gz" ) -mtime +$RETENTION_DAYS -delete

# После удаления можно послать сигнал nginx на повторное открытие лог-файлов,
# чтобы он продолжал писать в текущий файл, а не в удалённый.
kill -USR1 $(cat /var/run/nginx.pid 2>/dev/null) 2>/dev/null || true

Перед установкой скрипта на выполнение протестируйте его вручную, добавив echo перед -delete.

Создание службы и таймера в systemd

Предположим, скрипт сохранён как /usr/local/bin/cleanup-logs.sh с правами на выполнение (chmod +x).

Создаём службу, которая будет его запускать. Файл: /etc/systemd/system/cleanup-logs.service.

[Unit]
Description=Cleanup old nginx log files
After=network-online.target nginx.service
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup-logs.sh
User=root

[Install]
WantedBy=multi-user.target

Создаём таймер, который будет запускать эту службу. Файл: /etc/systemd/system/cleanup-logs.timer.

[Unit]
Description=Run log cleanup daily
Requires=cleanup-logs.service

[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=3600

[Install]
WantedBy=timers.target
  • OnCalendar=daily — запускать каждый день.
  • Persistent=true — если система была выключена в момент запуска, задача выполнится при следующем включении.
  • RandomizedDelaySec=3600 — добавить случайную задержку до часа, чтобы избежать пиковой нагрузки на диск при множестве таймеров.

Активируем и запускаем таймер:

sudo systemctl daemon-reload
sudo systemctl enable cleanup-logs.timer
sudo systemctl start cleanup-logs.timer

Проверить запланированный запуск можно командой systemctl list-timers.

Альтернатива: классический cron

Если система без systemd или вы предпочитаете cron, настройка проще. Откройте crontab для пользователя root: sudo crontab -e.

Добавьте строку для ежедневного запуска скрипта в 3 часа ночи:

0 3 * * * /usr/local/bin/cleanup-logs.sh

Но здесь нет встроенного журналирования в journald. Логи нужно прописывать вручную в строке crontab, перенаправляя вывод (>> /var/log/cleanup.log 2>&1), или они отправятся на почту root.

Что ещё можно автоматически чистить

Тот же принцип применяется к другим типам данных:

Цель очистки Типичный путь Критерий Особенности
Логи системы (journald) /var/log/journal/ По размеру или времени Использовать встроенную утилиту journalctl --vacuum-size=
Кэш пакетного менеджера /var/cache/apt/ или /var/cache/yum/ По времени Использовать apt clean или yum clean
Временные файлы (/tmp) /tmp По времени Система часто чистит сама, но можно добавить свою политику.
Сессии пользователей /var/run/screen/ или подобное По времени Аккуратно, чтобы не разорвать текущие сессии.

Типичные ошибки и как их избежать

  1. Удаление файлов, которые ещё открыты процессом. Это не освободит место на диске, пока процесс не закроет файл. Решение: после удаления логов отправлять сигнал приложению (как kill -USR1 для nginx) или использовать механизмы ротации логов, встроенные в само приложение (например, logrotate).
  2. Неправильный путь или маска файлов. Одна опечатка в скрипте приводит к удалению не тех данных. Всегда сначала выполняйте команду find с -print, сохраняйте вывод в файл и проверяйте.
  3. Отсутствие мониторинга. Вы настроили очистку и забыли. Скрипт мог сломаться из-за изменения структуры каталогов. Настройте алерты на свободное место на диске в системе мониторинга. Периодически проверяйте журнал выполнения таймера: journalctl -u cleanup-logs.service.

Почему не всегда нужен свой скрипт: logrotate

Для управления лог-файлами существует стандартный инструмент — logrotate. Его конфигурационные файлы находятся в /etc/logrotate.d/. Он может не только удалять старые файлы, но и переименовывать (ротировать), сжимать и создавать новые. Он интегрирован с большинством системных служб.

Часто достаточно добавить или изменить конфигурацию в /etc/logrotate.d/nginx, указав, сколько дней хранить логи и сколько архивов оставлять. logrotate вызывается из системного cron (/etc/cron.daily/logrotate).

Решение «писать свой скрипт или использовать logrotate» зависит от задачи. Для кастомных каталогов с данными приложений, временными файлами или резервными копиями свой скрипт более гибкий. Для стандартных логов служб логичнее использовать встроенный инструмент.

Что в итоге

Автоматизация удаления мусора, это не про то, чтобы один раз освободить место. Это про внедрение процесса, который будет поддерживать систему в чистоте постоянно, без вашего вмешательства. Вы тратите время на настройку, чтобы каждый месяц экономить минуты ручной работы и избегать часов простоя из-за переполненного диска. Это базовый навык, который устраняет одну из самых частых и раздражающих проблем.

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