Cron и systemd timers: что выбрать для автоматизации задач в Linux

Cron и systemd timers: что выбрать для автоматизации задач в Linux мая, 28 2026

Вы когда-нибудь замечали, как сервер молча выполняет рутинную работу, пока вы спите? Резервное копирование базы данных, очистка кэша или сбор логов - всё это происходит благодаря планировщикам задач. В мире Linux семейство операционных систем с открытым исходным кодом на базе ядра Linux уже десятилетия идет спор о том, какой инструмент лучше справляется с этой ролью. С одной стороны, есть проверенный временем cron, который работает с 1970-х годов. С другой - современный systemd timers механизм планирования задач, встроенный в систему инициализации systemd, предлагающий больше контроля и интеграции.

Многие администраторы до сих пор используют cron по привычке, не подозревая, что systemd timers могут решить их головные боли с логированием и зависимостями. Давайте разберемся, чем они отличаются, где каждый из них сияет, а где проигрывает, и как правильно настроить автоматизацию в вашей инфраструктуре в 2026 году.

Как работает классический cron

Cron - это фоновый демон (crond), который просыпается каждую минуту, проверяет файлы конфигурации (crontab) и запускает команды, если время совпадает с заданным расписанием. Его архитектура предельно проста: он не знает ничего о состоянии других сервисов, просто выполняет скрипт в указанное время.

Синтаксис cron состоит из пяти полей времени и самой команды:

  • Минуты (0-59)
  • Часы (0-23)
  • День месяца (1-31)
  • Месяц (1-12)
  • День недели (0-7, где 0 и 7 - воскресенье)

Например, запись 0 3 * * * /usr/bin/backup.sh означает запуск скрипта ежедневно в 3 часа ночи. Звездочка (*) означает «любое значение», а слэш (/) позволяет задавать интервалы, например, */5 для выполнения каждые 5 минут.

Главная проблема cron заключается в его изолированности. Он запускает задачи в минимальном окружении, поэтому переменные среды (PATH, HOME) часто отличаются от тех, что вы видите в терминале. Если вы забудете указать абсолютный путь к бинарнику (например, напишете python script.py вместо /usr/bin/python3 /path/to/script.py), задача упадет без объяснения причин. Кроме того, если сервер был выключен в момент планового запуска, cron просто пропустит эту задачу. Она не выполнится позже, даже если система включится через час.

Что такое systemd timers и почему они мощнее

Systemd система инициализации и управления службами для большинства современных дистрибутивов Linux изменила подход к управлению процессами. Вместо отдельного демона планировщика здесь используется связка двух файлов: .service (описывает, что делать) и .timer (описывает, когда делать).

Этот подход дает несколько ключевых преимуществ:

  1. Логирование. Вывод команд автоматически попадает в journalctl. Вам не нужно вручную перенаправлять stdout/stderr в файлы логов, как это часто делается в cron.
  2. Зависимости. Вы можете указать, чтобы задача запускалась только после старта сети или базы данных, используя директивы After= и Requires=.
  3. Персистентность. Директива Persistent=true гарантирует, что если сервер был выключен во время планового запуска, задача выполнится сразу после включения системы.
  4. Управление ресурсами. Так как задача запускается как сервис, вы можете ограничить её использование CPU и памяти через cgroups.

Синтаксис времени в systemd timers более читаемый. Вместо числовых полей вы используете конструкции вроде OnCalendar=daily, Mon..Fri 09:00 или *-*-* *:00/15 (каждые 15 минут). Это снижает риск ошибок при чтении конфигурации.

Сравнение: Cron против Systemd Timers

Сравнение характеристик cron и systemd timers
Характеристика Cron Systemd Timers
Сложность настройки Низкая (одна строка) Средняя (два файла: .service + .timer)
Логирование Требует ручной настройки редиректа вывода Автоматически в journalctl
Работа после простоя Пропускает пропущенные задачи Выполняет при Persistent=true
Зависимости от сервисов Отсутствуют Поддерживаются (After, Requires)
Пользовательский контекст Запускается от имени пользователя crontab Гибкая настройка User/Group в юните
Синтаксис времени 5 числовых полей (менее читаем) Естественный язык (OnCalendar)
Схематичное сравнение логики планировщиков задач

Когда использовать cron?

Не стоит демонизировать старый добрый cron. Для примерно 90-95% простых задач он остается лучшим выбором. Если вам нужно запустить простой скрипт очистки временных файлов раз в сутки или отправить отчет по email каждое утро, cron идеален.

Он особенно хорош в следующих случаях:

  • Минималистичные системы. В контейнерах Docker или легких Alpine-образах, где нет systemd, cron - единственный вариант.
  • Быстрые тесты. Чтобы быстро проверить скрипт, проще добавить одну строку в crontab -e, чем создавать пару файлов юнитов.
  • Пользовательские задачи. Обычным пользователям проще управлять своими заданиями через crontab, не требуя прав root для создания системных сервисов.

Когда переходить на systemd timers?

Если ваша инфраструктура растет, cron начинает становиться обузой. Вы теряете логи, не понимаете, почему задача не запустилась (сервер был перезагружен?), и сталкиваетесь с конфликтами путей.

Используйте systemd timers, когда:

  • Вам критически важно выполнение задачи даже после длительного простоя сервера (например, синхронизация данных).
  • Задача зависит от других сервисов (нужно, чтобы PostgreSQL был доступен перед запуском бекапа).
  • Вы хотите централизованного мониторинга состояния всех задач через systemctl list-timers.
  • Необходимо строгое ограничение ресурсов, чтобы тяжелая задача не убила производительность всего сервера.
Администратор настраивает автоматизацию в Linux

Практический пример настройки systemd timer

Давайте создадим задачу, которая будет очищать кэш каждые 15 минут и гарантированно выполнится после перезагрузки.

Шаг 1. Создайте файл сервиса /etc/systemd/system/cache-clean.service:

[Unit]
Description=Очистка кэша приложения

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

Шаг 2. Создайте файл таймера /etc/systemd/system/cache-clean.timer:

[Unit]
Description=Запуск очистки кэша каждые 15 минут

[Timer]
OnBootSec=5min
OnUnitActiveSec=15min
Persistent=true

[Install]
WantedBy=timers.target

Шаг 3. Активируйте таймер:

sudo systemctl daemon-reload
sudo systemctl enable --now cache-clean.timer

Теперь вы можете проверить статус любым удобным способом. Команда systemctl status cache-clean.timer покажет время следующего запуска, а journalctl -u cache-clean.service выдаст логи последнего выполнения.

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

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

С systemd timers новички часто забывают выполнить systemctl daemon-reload после изменения файлов конфигурации. Без этой команды systemd не увидит изменений. Также помните, что таймер сам по себе ничего не делает - он лишь запускает связанный сервис. Убедитесь, что имена файлов совпадают (например, mytask.timer и mytask.service).

Еще одна ловушка cron - перекрытие задач. Если задача выполняется дольше, чем интервал её запуска, начнется цепная реакция параллельных процессов. В systemd это решается проще: добавьте ConditionPathExists=!/var/run/mytask.lock в секцию [Unit] сервиса, чтобы предотвратить повторный запуск, если предыдущий еще идет.

Можно ли использовать cron и systemd timers одновременно?

Да, абсолютно. Они не конфликтуют друг с другом. Многие администраторы оставляют cron для простых пользовательских задач, а systemd timers используют для критически важных системных операций. Главное - следить, чтобы одни и те же скрипты не запускались дважды разными механизмами.

Как посмотреть логи задачи, запущенной через cron?

По умолчанию cron отправляет вывод в письмо пользователю, но многие почтовые демоны не настроены локально. Лучшая практика - явно перенаправлять вывод в файл лога внутри самого crontab: 0 3 * * * /path/to/script.sh >> /var/log/my-script.log 2>&1. В systemd логи доступны через journalctl -u service-name.

Что делать, если systemd timer не срабатывает?

Проверьте три вещи: 1) Выполнен ли systemctl daemon-reload после редактирования файлов. 2) Активирован ли таймер командой systemctl enable timer-name.timer. 3) Нет ли ошибок в связанном сервисе через systemctl status service-name.service. Иногда таймер ждет запуска сервиса, который падает с ошибкой.

Поддерживает ли cron выполнение задач с интервалом меньше минуты?

Нет, стандартный cron имеет разрешение в одну минуту. Для задач с интервалом в секунды или доли секунды обычно используют бесконечные циклы со sleep внутри скрипта, которые запускаются как обычные сервисы systemd, или применяют специализированные инструменты вроде at или очереди задач.

Безопаснее ли systemd timers по сравнению с cron?

Да, в некоторой степени. Systemd позволяет явно задать пользователя и группу исполнения, ограничить доступ к сетевым интерфейсам, файловой системе и другим ресурсам через sandboxing-директивы. Cron запускает задачи с правами владельца crontab, что может быть рискованно, если скрипт содержит уязвимости.