Задачи по расписанию на сервере: cron и systemd-таймеры

Почти всё, что на сервере должно происходить регулярно, делается по расписанию: резервные копии ночью, очистка временных файлов, отчёты по утрам, продление сертификатов. Настраивается это одной строкой, и именно поэтому чаще всего ломается молча - задача не выполняется, а узнают об этом через неделю, когда понадобился бэкап.

Разберём формат расписания, готовые примеры под типовые задачи, четыре причины, по которым команда работает руками и молчит по расписанию, и когда стоит перейти с cron на таймеры systemd.

Как читается строка расписания

пять полей расписания и типовые варианты записи.
пять полей расписания и типовые варианты записи.

Задача описывается одной строкой: пять полей времени, затем команда.

30 3 * * * /home/user/backup.sh

Читается справа налево от команды: запускать /home/user/backup.sh каждый день в 3 часа 30 минут. Звёздочка означает любое значение.

Порядок полей: минута, час, день месяца, месяц, день недели. Запомнить проще так: чем правее поле, тем крупнее единица времени.

Открыть свой список задач:

crontab -e

Посмотреть, что уже настроено:

crontab -l

Готовые примеры

РасписаниеКогда сработает
0 * * * *Каждый час, ровно в начале
*/15 * * * *Каждые 15 минут
30 3 * * *Каждый день в 3:30 ночи
0 4 * * 1Каждый понедельник в 4 утра
0 2 1 * *Первого числа каждого месяца в 2 ночи
0 9 * * 1-5По будням в 9 утра

Практическое правило: тяжёлые задачи ставят на ночь и разносят по времени. Если бэкап базы и архивация логов запустятся одновременно в 3:00, они будут мешать друг другу и нагрузят диск вдвое сильнее.

Четыре причины, по которым задача молчит

Классическая ситуация: команда прекрасно работает, если запустить её руками, и не делает ничего по расписанию. Причин почти всегда четыре.

Урезанное окружение. Это главная. Cron запускает команды с минимальным набором переменных, и привычные пути к программам могут быть недоступны. Лечится указанием полного пути:

30 3 * * * /usr/bin/python3 /home/user/script.py

Относительные пути внутри скрипта. Задача стартует не из вашего домашнего каталога, поэтому обращения к файлам вида ./data.csv не находят ничего. В скриптах для расписания пути пишут полностью.

Вывод уходит в никуда. Если команда падает с ошибкой, вы об этом не узнаете. Поэтому вывод перенаправляют в файл:

30 3 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1

Запись 2>&1 означает, что в файл попадут и обычные сообщения, и ошибки. Без неё в журнале останется только половина картины.

Часовой пояс сервера. Сервер нередко живёт по UTC, и задача, поставленная на 3 часа ночи, срабатывает в другое по вашим меркам время. Проверить и при необходимости поправить:

timedatectl

Как убедиться, что всё работает

Проверять надо сразу после настройки, а не когда понадобится результат.

  • Поставьте временное расписание на ближайшие минуты, дождитесь срабатывания и верните обратно.
  • Смотрите свой лог из перенаправления вывода: там будет и результат, и ошибка.
  • Проверьте системный журнал: факт запуска задачи фиксируется, даже если сама она упала.
  • Добавьте признак успеха. Скрипт бэкапа должен не просто отработать, а оставить файл нужного размера. Проверять стоит именно это, см. резервное копирование VPS.

Отдельная хорошая практика - уведомление при сбое. Задача, которая молча перестала выполняться, обнаруживается в худший момент. Как настроить оповещения, разобрано в статье мониторинг VPS.

Когда лучше systemd-таймеры

Cron прост и есть везде, но у современной альтернативы есть преимущества, которые заметны на боевом сервере.

  • Всё пишется в системный журнал. Не нужно самому перенаправлять вывод: результат каждого запуска сохраняется и ищется по имени службы.
  • Пропущенные запуски выполняются. Если сервер был выключен в момент срабатывания, таймер может запустить задачу сразу после включения. Cron просто пропустит.
  • Есть зависимости. Задачу можно привязать к тому, что база уже поднялась, а сеть доступна.
  • Задача описывается службой. Тот же механизм, что и для приложений, см. как выложить приложение на сервер.

Взамен настройка сложнее: вместо одной строки нужны два файла - описание задачи и описание расписания.

Практический выбор: простая периодическая задача - cron, важная задача на боевом сервере - таймер. Для очистки временных файлов первое, для ночного бэкапа базы второе.

Что обычно ставят по расписанию

  • Резервные копии базы и файлов, с выгрузкой копии вне сервера.
  • Очистку: старые логи, временные файлы, устаревшие бэкапы.
  • Обновление сертификатов. Обычно настраивается автоматически при выпуске, но проверить стоит, см. SSL-сертификат на VPS.
  • Отчёты и выгрузки: ночная сборка статистики, отправка сводки утром.
  • Плановые задачи приложения вместо встроенного механизма, который запускается при визите пользователя.

Частые ошибки

Не перенаправляют вывод. Задача падает молча, и об этом узнают через недели.

Используют короткие имена команд. В урезанном окружении cron привычная команда может не найтись. Пути пишут полностью.

Ставят всё на 3:00. Задачи сталкиваются и мешают друг другу, нагружая диск.

Забывают про часовой пояс. Ночная задача выполняется днём в разгар нагрузки.

Не проверяют результат, а только факт запуска. Скрипт отработал и создал пустой архив - формально всё хорошо.

Копят логи задач без ротации. Файл растёт месяцами и однажды заполняет диск.

Частые вопросы

Как настроить запуск задачи по расписанию? Выполнить crontab -e и добавить строку из пяти полей времени и команды. Например, 30 3 * * * означает каждый день в 3:30.

Почему скрипт работает вручную, но не по расписанию? Чаще всего из-за урезанного окружения и относительных путей. Указывайте полные пути к программам и файлам, а вывод перенаправляйте в лог.

Как узнать, что задача выполнилась? Перенаправить вывод в файл с добавлением 2>&1 и смотреть его. Факт запуска дополнительно виден в системном журнале.

Что означают звёздочки в расписании? Любое значение поля. Пять полей идут в порядке: минута, час, день месяца, месяц, день недели.

Чем systemd-таймеры лучше cron? Пишут результат в системный журнал, умеют выполнять пропущенные запуски и учитывать зависимости. Настройка сложнее, поэтому их берут для важных задач.

Как поменять часовой пояс сервера? Посмотреть текущий командой timedatectl и при необходимости задать нужный. Это стоит сделать до настройки расписаний.

Можно ли запускать задачу чаще раза в минуту? Штатно нет, минимальный интервал в cron - минута. Для более частых запусков используют службу, которая работает постоянно.


Нужен сервер под регулярные задачи? VPS на NVMe от 459 руб в месяц - полный root-доступ, cron и systemd из коробки, площадки в Москве, Казани и Амстердаме. Активация за 3 минуты, первые 7 дней - тестовый период с возвратом средств.