cron в systemd: отказы службы и незапустившиеся задачи
Сама служба cron падает редко — чаще «не работает» отдельная задача. Причины почти всегда две: ошибка в строке расписания и разница окружения, потому что задача выполняется без вашего профиля, с коротким PATH и без переменных оболочки.
О службе
Служба называется cron.service в Debian и Ubuntu и crond.service в RHEL. Она читает файлы пользователей (crontab -l), системный /etc/crontab и каталоги /etc/cron.d и /etc/cron.*. Ошибка в любом файле из /etc/cron.d может помешать выполнению соседних задач, поэтому проверять стоит все.
Задачи выполняются с минимальным окружением: PATH обычно короткий, домашний каталог задан, а переменные из .bashrc и .profile не читаются. Это главная причина ситуации «в терминале работает, из cron нет»: команда просто не находится.
Вывод задачи по умолчанию уходит письмом локальному пользователю. Если почтовой службы нет, вывод теряется, и об ошибках никто не узнаёт. Поэтому в строке задачи стоит явно перенаправлять вывод в файл или в журнал через logger.
Как устроена
| Имя unit | cron.service в Debian и Ubuntu, crond.service в RHEL |
|---|---|
| Где задачи | crontab пользователей, /etc/crontab, /etc/cron.d, каталоги /etc/cron.hourly и далее |
| Права на файлы в /etc/cron.d | владелец root, права не шире 0644, без точки в имени файла |
| Окружение задачи | минимальное: короткий PATH, без переменных вашего профиля |
| Куда идёт вывод | письмом локальному пользователю; без почтовой службы теряется |
Частые ошибки
4 записи базы отмечены за этой службой.
Коды выхода
- status=1/FAILURE в systemdКод 1/FAILURE означает, что программа запустилась и сама завершилась с ошибкой. Как найти настоящую причину в журнале службы.
- status=127 в systemd: команда не найденаКод 127 без имени: оболочка не нашла команду. Появляется, когда ExecStart запускает скрипт или sh -c, а внутри команды нет.
Сообщения журнала
- Permission denied в журнале службыОтказ в доступе у службы systemd: права на файл, каталоги по пути, пользователь службы, параметры изоляции, SELinux и AppArmor.
Ошибки служб
- Задача cron не выполняетсяЗадача в crontab не запускается: короткий PATH, права на файл задачи, точка в имени файла, отсутствие перевода строки.
Коды выхода этой службы
Числа в status=N ниже 200 назначает сама программа, 200 и выше — systemd, когда не смог подготовить запуск.
Диагностика
Состояние службы; для RHEL — crond.
systemctl status cron --no-pager -lЗаписи о запусках задач: видно, вызывалась ли задача вообще.
journalctl -u cron --since "1 day ago" --no-pager | tail -40Файлы задач и их права: файл с точкой в имени или широкими правами игнорируется.
sudo ls -l /etc/cron.d/ && sudo crontab -l -u rootПоказывает, какие скрипты из каталога действительно будут выполнены.
sudo run-parts --test /etc/cron.dailyПараметры unit, которые тут важны
Частые вопросы
Задача в crontab не выполняется, хотя команда в терминале работает.
Почти всегда дело в PATH: пишите полные пути к программам или задайте PATH в начале crontab. Проверить можно, добавив в задачу перенаправление вывода в файл и посмотрев, что она пишет.
Что лучше для регулярных задач: cron или таймеры systemd?
Таймеры дают журнал, зависимости, ограничения ресурсов и учёт пропущенных запусков. Cron проще и привычнее. Для задач, которые важно контролировать, таймеры удобнее; для разовой мелочи разницы нет.
Источники
- crontab(5)
- systemd.timer(5)
- Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)