systemd-таймеры вместо cron

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

Задача описывается двумя файлами. Сервис — что запускать:

# /etc/systemd/system/report.service
[Unit]
Description=Ночной отчёт

[Service]
Type=oneshot
ExecStart=/usr/local/bin/report.sh

Таймер — когда запускать:

# /etc/systemd/system/report.timer
[Unit]
Description=Запуск ночного отчёта

[Timer]
OnCalendar=*-*-* 03:30:00
RandomizedDelaySec=15min
Persistent=true

[Install]
WantedBy=timers.target

Включаем и проверяем:

sudo systemctl daemon-reload
sudo systemctl enable --now report.timer
systemctl list-timers report.timer
journalctl -u report.service --since today

Полезные мелочи

  • Persistent=true — если в 03:30 машина была выключена, задача выполнится сразу после загрузки.
  • RandomizedDelaySec размазывает запуски, чтобы десяток серверов не пошёл в одно хранилище в одну и ту же секунду.
  • Проверить выражение расписания: systemd-analyze calendar 'Mon..Fri 09:00' — покажет, когда будет следующий запуск.
  • Запустить задачу вне расписания: systemctl start report.service.

Из минусов — два файла вместо одной строки в crontab. Но за журнал и предсказуемость эту цену я плачу с радостью.