STEADRUN

Cron не отрабатывает: чек-лист причин

Обновлено 02.10.2026

Задача в crontab есть, а результата нет. Ниже причины, сгруппированные по тому, что именно не работает. Сначала выясните, запускал ли cron задачу вообще. Для этого посмотрите журнал:

journalctl -u cron --since today | grep backup.sh   # в CentOS и AlmaLinux: -u crond

Если строки CMD (…) с Вашей задачей нет, cron её не запускал, начните с первых разделов. Если строка есть, задача запустилась и упала, переходите к разделам ниже. Подробная пошаговая проверка — в руководстве «Как проверить, что cron выполняется».

Почему cron вообще не запускает задачи?

  • Сервис остановлен. systemctl status cron должен показывать active (running). Запустить и включить автозапуск: sudo systemctl enable --now cron.
  • Задача в контейнере. В Docker-контейнере cron обычно не запущен, даже если установлен.
  • Пользователю запрещён cron. Если на сервере есть файл /etc/cron.allow, cron работает только для перечисленных в нём пользователей. Если есть /etc/cron.deny, пользователи из него cron использовать не могут.

Почему cron не видит задачу?

  • Задача у другого пользователя. crontab -l показывает только Ваш crontab. Задачи deploy смотрите через sudo crontab -u deploy -l.
  • Нет перевода строки в конце. Последняя строка crontab без перевода строки после неё во многих версиях cron пропускается. Добавьте пустую строку в конец файла.
  • Файл в /etc/cron.d/ игнорируется. В Debian и Ubuntu cron пропускает файлы, в имени которых есть точка, например backup.cron. Ещё файл должен принадлежать root и быть недоступен для записи другим пользователям. И в этих файлах между расписанием и командой нужно имя пользователя: 0 3 * * * deploy /home/deploy/backup.sh.
  • Скрипт в /etc/cron.daily/ не запускается. Скрипты из этих папок запускает run-parts, а в Debian и Ubuntu он пропускает файлы с точкой в имени. backup.sh запущен не будет, переименуйте его в backup. Проверить, что попадёт в запуск: run-parts --test /etc/cron.daily.

Почему задача запускается не в то время?

  • Ошибка в расписании. * 3 * * * значит «каждую минуту с 03:00 до 03:59», а не «в 03:00». Разобрать выражение можно в руководстве о расписании cron.
  • День месяца и день недели вместе. 0 3 1 * 1 срабатывает первого числа или в понедельник.
  • Часовой пояс. Cron работает в часовом поясе сервера, а он часто UTC. Проверьте командой date. Если часовой пояс меняли, перезапустите cron: sudo systemctl restart cron.
  • Сервер был выключен. Cron не выполняет пропущенные запуски. Если в 03:00 сервер перезагружался, задача не выполнится до следующего раза.

Почему задача запускается, но падает?

Сначала сохраните вывод задачи, иначе причину не узнать:

0 3 * * * /home/deploy/backup.sh >> /var/log/backup.log 2>&1

Дальше смотрите на текст ошибки в логе.

  • command not found. У cron короткий PATH, обычно только /usr/bin:/bin. Пишите полные пути к программам (/usr/bin/php, /usr/local/bin/node) или задайте PATH в начале crontab.
  • Permission denied. У скрипта нет права на запуск: chmod +x /home/deploy/backup.sh. Или задача работает от пользователя, которому не хватает прав на файлы.
  • /bin/bash^M: bad interpreter. Скрипт сохранён с переводами строк Windows. Исправить: sed -i 's/\r$//' backup.sh.
  • No such file or directory для файлов, которые точно есть. Скрипт открывает файлы по относительному пути, а cron запускает его из домашней папки. Добавьте cd в нужную папку или используйте абсолютные пути.
  • Команда обрезана. Символ % в crontab означает перевод строки. date +%F нужно писать как date +\%F.
  • Не хватает переменных окружения. Cron не читает .bashrc и .profile. Переменные, которые есть в терминале, в cron пустые. Задайте их в начале crontab или в самом скрипте.
  • Синтаксис bash не работает. Cron запускает команду через /bin/sh. Если в строке crontab есть конструкции bash, вынесите команду в скрипт с #!/bin/bash в первой строке.

Быстро проверить, упадёт ли команда в окружении cron, можно без ожидания:

env -i HOME="$HOME" SHELL=/bin/sh PATH=/usr/bin:/bin /bin/sh -c '/home/deploy/backup.sh'

Почему задача иногда не выполняется?

  • Задачи наслаиваются. Если задача иногда идёт дольше интервала, следующий запуск начнётся поверх предыдущего, и они мешают друг другу. Запретить наслоение можно через flock: /usr/bin/flock -n /tmp/import.lock /home/deploy/import.sh.
  • Предыдущий запуск завис. С flock зависшая задача держит блокировку, и новые запуски молча пропускаются. Ограничьте время работы: timeout 30m /home/deploy/import.sh.
  • Внешние сервисы. Задача ждёт ответа от API или базы, и иногда не дожидается. Это видно только в её собственном логе.

Как узнавать о таких сбоях сразу?

Все причины выше объединяет одно: cron о них не сообщает. Задача просто перестаёт делать свою работу, и это обнаруживают, когда что-то уже сломалось.

Чтобы узнавать сразу, задача должна сама сообщать, что отработала, а кто-то должен ждать этого сообщения. Так работает Steadrun. В конец строки crontab добавляется запрос на адрес проверки, и если он не пришёл вовремя, приходит алерт в Telegram или на почту.

0 3 * * * /home/deploy/backup.sh && curl -fsS -m 10 --retry 3 -o /dev/null https://steadrun.ru/ping/ВАШ-UUID

Так ловится любая причина из списка, будь то остановленный cron, ошибка в расписании или упавший скрипт. Как подключить за пять минут, описано в быстром старте. Бесплатно можно следить за пятью задачами.