systemd-таймеры вместо cron
cron прекрасен, пока всё работает. Когда что-то ломается, выясняется, что вывод задачи никуда не сохранился, а узнать, запускалась ли она вообще, можно только по косвенным признакам. Таймеры systemd решают обе проблемы.
Пара «сервис + таймер»
# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
Nice=10
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup every night
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now backup.timer
systemctl list-timers
Что я получил
- Логи. Весь вывод задачи лежит в
journalctl -u backup, с датами и кодом возврата. - Пропущенные запуски.
Persistent=trueдогоняет задачу, если сервер был выключен в нужное время. - Ресурсы.
Nice=,CPUQuota=,TimeoutStartSec=— тяжёлая задача не задушит основной сервис. - Ручной запуск той же самой задачи:
systemctl start backup.service.
Шаблонные сервисы
Если одна и та же задача запускается с разными параметрами, удобен шаблон check@.service с %i внутри. Тогда check@home.service и check@office.service — два экземпляра одного описания, а для каждого можно завести свой таймер со своим расписанием.
Пример из жизни: мой скрипт DuckDNS тихо падал каждые пять минут с ошибкой
203/EXEC, потому что в файле не было строки #!/bin/bash. В cron я бы этого не заметил, а systemctl status показал проблему сразу.