Cron-задачи на сервере: частые ошибки и решения
Cron-задачи на сервере коварны тем, что молчат. Задание вроде добавлено, а бэкап не делается, отчёт не приходит, очистка не идёт — и ни строчки ошибки. Почти всегда причина не в самом планировщике, а в нескольких типовых промахах: урезанное окружение, относительные пути, забытое логирование. Разберём эти грабли по порядку и научимся быстро находить, почему задача не работает.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Ошибка: работает в терминале, но не по cron
Самая частая и сбивающая с толку ситуация. Вы запускаете команду руками — всё отлично. Ставите ту же команду в crontab — тишина. Причина в том, что cron исполняет задания в сильно урезанном окружении: минимальный набор переменных, короткий PATH, часто иной рабочий каталог. Программа, которую в терминале система находит сама, по cron оказывается «не найдена», и задача молча падает.
Решение — не полагаться на окружение вовсе. Указывайте абсолютные пути ко всему: к интерпретатору, к скрипту, к файлам данных. Вместо python3 script.py пишите полный путь:
0 3 * * * /usr/bin/python3 /home/user/app/script.py
Узнать полный путь к программе помогает команда which, выполненная в терминале. Если скрипт опирается на переменные окружения, задайте их явно в начале самого скрипта или в crontab. Это первое, что нужно проверить, когда «в терминале работает, а по расписанию нет».
Ошибка: задача падает молча, без следов
Вы не знаете, запускалась ли задача и что пошло не так, потому что нет никакого вывода. Cron по умолчанию не пишет результат на экран — он пытается отправить его локальной почтой, которой на сервере обычно нет, и весь вывод исчезает в никуда. Отсюда ощущение, что задача «просто не работает».
Обязательно перенаправляйте и стандартный вывод, и ошибки в лог-файл:
0 3 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1
Часть 2>&1 направляет ошибки туда же, куда и обычный вывод. Теперь любая проблема попадёт в лог, и отладка станет осмысленной. Дополнительно факт запуска виден в системном журнале: grep CRON /var/log/syslog покажет, вызывал ли cron вашу команду. Разделение простое — если в журнале запуск есть, а в вашем логе ошибка, чините команду; если запуска нет вовсе, чините расписание или сохранение задания.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPSОшибка: неверный часовой пояс
Задача исправно работает, но срабатывает не в то время: бэкап, поставленный на три ночи, идёт в шесть утра или наоборот. Причина — часовой пояс сервера отличается от того, что вы держите в голове. Cron ориентируется строго на системное время, и если сервер живёт по UTC, а вы рассчитывали на московское, все задания смещаются.
Проверьте пояс и при необходимости выставьте нужный:
timedatectl
timedatectl set-timezone Europe/Moscow
После смены пояса задачи начнут срабатывать в ожидаемое время. Отдельно учтите: если на сервере крутятся задачи, чувствительные к точному времени запуска, лучше один раз согласовать пояс со всей командой, чем каждый раз переводить часы в уме. Это особенно важно, когда серверов несколько и они в разных регионах.
Ошибка: нет переноса строки в конце crontab
Малоизвестная, но реальная грабля: если последняя строка crontab не завершается переносом строки, cron может её проигнорировать. Задание вроде добавлено, видно в crontab -l, но не выполняется, потому что планировщик не считает последнюю строку полноценной.
Решение простое — всегда оставляйте пустую строку в конце crontab после последнего задания. Если вы редактируете таблицу через crontab -e в нормальном редакторе, он обычно добавляет перенос сам, но при программной подстановке заданий или копировании из других источников об этом легко забыть. Когда задание упорно не запускается, а всё остальное верно, проверьте эту деталь — она экономит массу времени на пустом месте.
Ошибка: права и не тот пользователь
Задача, которая должна писать в защищённый каталог или обращаться к чужим файлам, падает на правах доступа. Частая причина — crontab заведён не под тем пользователем. У каждого пользователя своя таблица, и задача выполняется от его имени с его правами. Если бэкап должен читать системные файлы, а задание висит в crontab обычного пользователя, доступа не хватит.
Определитесь, от чьего имени должна идти задача, и правьте нужный crontab. Для системных задач бывает уместен crontab суперпользователя, но давать root лишнего не стоит — лучше выдать конкретные права нужному пользователю. Проверьте и владельца самих скриптов: они должны быть исполняемыми и доступными тому, кто их запускает. Аккуратное разграничение прав здесь важнее, чем кажется, — задача с чрезмерными правами опаснее, чем упавшая.
Ошибка: задачи накладываются друг на друга
Тяжёлая задача не успевает завершиться до следующего запуска по расписанию, и на сервере копятся её параллельные копии, съедая память и диск. Это типично для бэкапов и обработки данных, поставленных на частый интервал: один прогон ещё идёт, а cron уже стартует следующий.
Решение — блокировка через flock, которая не даёт запуститься новой копии, пока работает предыдущая:
*/10 * * * * /usr/bin/flock -n /tmp/job.lock /home/user/job.sh >> /var/log/job.log 2>&1
Флаг -n означает «не ждать»: если задача ещё выполняется, новый запуск просто пропускается. Так вы гарантируете, что в любой момент работает только один экземпляр. Если же задача честно не укладывается в интервал даже без наложений, это сигнал, что ей не хватает ресурсов сервера, — и стоит либо оптимизировать её, либо перейти на более мощный VPS.
Как быстро находить причину сбоя
Сведём отладку cron к простому алгоритму. Сначала смотрим системный журнал: grep CRON /var/log/syslog отвечает на вопрос, запускалась ли задача вообще. Если запуска нет — проблема в расписании, переносе строки или сохранении задания. Если запуск есть, открываем лог-файл задачи, куда мы перенаправили вывод, и читаем ошибку. Обычно это ненайденная команда (лечится абсолютными путями), нехватка прав или падение самого скрипта.
Такой порядок — журнал, затем лог задачи — локализует почти любую проблему за пару минут. Чтобы отладка вообще была возможна, логирование и абсолютные пути должны стоять с самого начала, а не добавляться после первого сбоя. У MAATRIX сервер выдаётся с root и чистым окружением, где вы настраиваете время, права и планировщик под себя, а нарастить ресурсы под тяжёлые регулярные задачи можно в любой момент.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPSОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Команда работает в терминале, но не по cron. Почему?
Cron исполняет задания в урезанном окружении с коротким PATH. Указывайте абсолютные пути к интерпретатору, скрипту и данным.
Как понять, почему задача упала?
Перенаправьте вывод в лог через >> файл 2>&1 и проверьте факт запуска в системном журнале командой grep CRON /var/log/syslog.
Задачи срабатывают не в то время.
Дело в часовом поясе сервера. Проверьте его командой timedatectl и выставьте нужный пояс.
Как не дать задаче наложиться саму на себя?
Оберните команду в flock -n с файлом-блокировкой — новый запуск пропускается, пока работает предыдущий.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.