Короткий ответ

На Ubuntu демон называется cron.service (пакет cron), не crond. Порядок: жив ли unit, есть ли строка в том crontab, который вы думаете (root vs admin), сработал ли он по /var/log/syslog или journalctl -t CRON, какой PATH в неинтерактивной среде, куда ушла почта с stderr. «Вручную из SSH работает» ничего не доказывает: у интерактива другой PATH, tty, env. Не переносите всё на systemd timer, пока не прочитали cron — но если уже timer, смотрите systemd timer.

Хост host.example (10.0.20.10), пользователь admin.

Симптомы и как отличить

  • скрипт из /usr/local/bin в cron «не идёт»;
  • cron.daily не крутит apt (на 24.04 часть ушла в timers — не путать);
  • время срабатывания «не то» — NTP;
  • unit failed — пересечение с systemd.
Место заданияКак смотреть
crontab -u admin -lпользовательский
/etc/crontabсистемный, поле user
/etc/cron.d/*пакеты и ваши drop-in
/etc/cron.dailyrun-parts, имена без точек

Возможные причины

  1. cron.service stopped/disabled.
  2. crontab другого пользователя.
  3. PATH=/usr/bin:/bin — нет /usr/local/bin.
  4. % в crontab — перевод строки, ломает команду.
  5. stderr ушёл на mail, локальный MTA не настроен, вы не смотрите /var/mail/admin.
  6. anacron vs машины, которые выключены ночью (для daily).
  7. AppArmor/права на скрипт — permission.
  8. Часовой пояс / UTC в /etc/crontab.

Диагностика

systemctl status cron.service --no-pager -l
systemctl is-enabled cron.service
journalctl -u cron -b --no-pager | tail -n 50
journalctl -t CRON --since 'today' --no-pager | tail
grep CRON /var/log/syslog | tail

Списки заданий:

sudo crontab -l
sudo crontab -u admin -l
cat /etc/crontab
ls -l /etc/cron.d /etc/cron.daily /etc/cron.hourly

Проверка run-parts имён:

run-parts --test /etc/cron.daily

Окружение: добавьте временно в задание * * * * * /usr/bin/env > /tmp/cron.env (и уберите через минуту). Сравните с env в SSH.

Почта:

ls -l /var/mail/admin /var/mail/root
sudo tail -n 30 /var/mail/admin

Если MAILTO="" — вывод уничтожается. Если MAILTO внешний и нет MTA — тишина.

Время:

timedatectl
date
grep CRON_TZ /etc/crontab

systemd-cat не заменяет syslog CRON. На 24.04 rsyslog может быть не установлен — тогда только journal.

Решение

Сценарий A. Демон не запущен

sudo systemctl enable --now cron.service
systemctl is-active cron.service

Сценарий B. PATH

В crontab:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=admin@host.example
0 3 * * * /usr/local/bin/backup.sh >>/var/log/backup-cron.log 2>&1

Абсолютные пути в скрипте обязательны.

Сценарий C. % и кавычки

Экранируйте % как \% внутри команды crontab.

Сценарий D. daily не выполняется на ноутбуке-сервере

Пакет anacron догоняет пропущенные daily. На 24/7 сервере cron.daily из /etc/crontab (обычно 6:25). Проверьте, не отключён ли START_HOURS_RANGE в anacrontab.

Сценарий E. Дубль timer + cron

Ubuntu apt-daily.timer и cron.daily могут путать ожидания. Смотрите systemctl list-timers. Не чините apt через cron, пока apt красный.

Сценарий F. Права

Скрипт 750, владелец root, без world-write. cron не запустит crontab с плохими правами (для /etc/cron.d: не writable others).

ls -l /etc/cron.d/app-backup
sudo chmod 644 /etc/cron.d/app-backup

Почему «в crontab есть» не значит «выполнилось»

Строка с 2>&1 в файл, который admin не может писать, даёт отказ, видимый только в mail root. Проверьте ls -l каталога лога и namei.

/etc/cron.allow и cron.deny: если allow существует, пользователь должен быть в нём. На Ubuntu файлов часто нет — тогда все локальные пользователи могут иметь crontab, root всегда может.

ls -l /etc/cron.allow /etc/cron.deny

anacron на сервере, который живёт 24/7, всё равно ставится в desktop-seed; на ubuntu-server minimal его может не быть. Тогда пропущенный daily из-за выключения не догоняется. Для бэкапов лучше systemd timer с Persistent=true.

Секундные расписания в cron невозможны: минимум минута. Пять записей * * * * * с sleep 10 — антипаттерн, берите timer OnCalendar=*:*:0/10.

Локальный exim4 в режиме local-only кладёт bounce в /var/mail. Если диск inode-полный из-за писем cron — вы в статье про inode, не «cron сломан».

На 24.04 часть ежедневных задач Ubuntu (apt, fstrim, man-db, logrotate) сидит в systemctl list-timers, не в cron. Если вы правите /etc/cron.daily/apt-compat и ничего не происходит — смотрите apt-daily.timer. Не дублируйте одно и то же задание в cron и timer: получите два бэкапа и lock.

Поле пользователя в /etc/crontab (семь полей) часто забывают и пишут как в crontab -e (пять). Строка тогда не парсится или выполняется от неверного user. grep файл и считайте колонки.

Проверка, что демон видит таблицу после crontab -e:

sudo kill -HUP $(systemctl show -p MainPID --value cron)
journalctl -u cron --since '1 min ago'

HUP заставляет перечитать crontabs. Если после правки ждали до часа — могли просто не попасть в минуту расписания.

Как проверить, что проблема устранена

Минутный тест, затем удалить:

* * * * * /bin/date >> /tmp/cron-test.stamp 2>&1
sleep 70
cat /tmp/cron-test.stamp
journalctl -t CRON --since '5 min ago'

Боевой job: смотрите целевой артефакт (дамп, файл) и лог, не «в crontab строка есть».

Если не помогло

  • Секундной точности нет — cron минутный, для секунд systemd timer OnCalendar.
  • Контейнер без cron — запускайте timer на хосте.
  • SELinux не ваш случай на Ubuntu; AppArmor на скрипте в home — логи DENIED.

Профилактика

  • Логи в файл, не только MAILTO.
  • Абсолютные пути, явный PATH.
  • Мониторинг mtime артефакта job, не процесса cron.
  • Код в git, в cron.d только одна строка вызова.

FAQ

crontab -e от sudo vs root?

sudo crontab -e правит root. sudo -u admin crontab -e — admin. Это разные таблицы.

Нужен ли crond в имени unit?

Нет, Ubuntu: cron.

Почему не вижу mail?

Нет postfix/nullmailer, или MAILTO="", или rsyslog не пишет /var/mail. Смотрите journal.

Можно ли cron в контейнере Docker?

Можно, но часто лучше timer/оркестратор. PID1 должен reap.

crontab пуст, job есть

Ищите /etc/cron.d. Пакеты кладут туда.