Гайды

Почему cron-задача не запускается — и как заставить крон признаться

Иллюстрация: будильник-планировщик прозвенел в пустой комнате — задача-конверт так и лежит нетронутой

Знакомая ситуация: ты настроил cron-задачу — скрипт должен запускаться каждое утро. Руками запускаешь — работает идеально. А по расписанию — тишина. Ни результата, ни ошибки, ничего.

Вот главное, что нужно понять про крон: он молчит всегда. Успех выглядит как тишина. Поломка выглядит как тишина. Крон не покажет ошибку на экране — экрана у него нет. Поэтому чинить его наугад бесполезно — сначала заставим его признаться, что происходит, а потом разберём три причины, которые покрывают почти все случаи.

Сначала — включи кроне голос

Один приём превращает невидимую поломку в читаемую ошибку: сохраняй вывод задачи в файл. Допиши в конец строки расписания:

0 8 * * * /home/you/backup.sh >> /tmp/backup.log 2>&1

>> /tmp/backup.log пишет обычный вывод в файл, 2>&1 добавляет туда же ошибки. Теперь после каждого запуска в /tmp/backup.log будет либо результат, либо текст ошибки — то самое сообщение, которое ты «не видишь». Это логи в миниатюре: без них отладка крона — гадание.

И второй приём — тестовая задача-минутка, чтобы не ждать до утра:

* * * * * date >> /tmp/tick.log

Пять звёздочек = «каждую минуту». Подожди две минуты и загляни в /tmp/tick.log. Появляются строки с датой — крон жив, проблема в твоей задаче (причины 1–2). Файл пуст — не запускается сам крон (причина 3).

Причина 1: крон живёт в пустом окружении

Самая частая причина «руками работает, по расписанию нет». Когда ты запускаешь скрипт, он наследует твоё окружение: настроенный PATH, переменные из профиля, всё, что подхватил терминал. Когда скрипт запускает крон, окружение почти пустое: PATH урезан до пары системных папок, твоих переменных нет.

Как проверить: посмотри в лог из первого шага. Ошибка command not found про node, python3, pnpm — это оно: крон просто не знает, где лежит программа.

Как починить: укажи полный путь к программе. Узнай его командой which node (например, /usr/local/bin/node) и пиши в задаче полный вариант:

0 8 * * * /usr/local/bin/node /home/you/bot/daily.js >> /tmp/bot.log 2>&1

Переменные вроде API-ключей из твоего профиля крон тоже не увидит — загружай их внутри самого скрипта (например, читай .env-файл), а не надейся на окружение.

Причина 2: скрипт запускается не из той папки

Твой скрипт читает config.json или пишет в data/? Руками ты запускаешь его из папки проекта — и относительные пути работают. Крон запускает задачи из домашней папки — и скрипт ищет config.json там, не находит и падает.

Как проверить: в логе будут ошибки вида no such file or directory / ENOENT про твои же файлы.

Как починить: перейди в папку проекта прямо в задаче, через &&:

0 8 * * * cd /home/you/bot && /usr/local/bin/node daily.js >> /tmp/bot.log 2>&1

Либо используй в скрипте только абсолютные пути. Первый вариант проще и чинит всё разом.

Причина 3: машине, где крон, положено не спать

Крон запускает задачу в назначенную минуту на работающей машине. Ноутбук закрыт, компьютер уснул — минута прошла, обычный крон задачу просто пропустил и навёрстывать не будет. Если ты ставишь расписание на своём ноутбуке «на каждое утро» — оно будет срабатывать ровно в те утра, когда ноутбук открыт.

Как проверить: тестовая минутка из первого шага тикает, пока ты за компьютером, но «боевые» утренние запуски пропадают.

Как починить: задачам с расписанием место на машине, которая не спит, — сервере или бесплатном хостинге с поддержкой cron/scheduled jobs. Это тот же случай, что и с ботом, который умирает при закрытии ноутбука: твой ноутбук — не сервер.

И бонус-грабля, раз уж редактируешь crontab: каждая задача — одна строка, а файл должен заканчиваться переводом строки. Задачу, приклеенную к последней строке без Enter в конце, крон молча игнорирует — да, снова молча.

Как проверить синтаксис расписания?

Пять полей — минута, час, день месяца, месяц, день недели: 0 8 * * * = «в 8:00 каждый день». Не уверен — вставь строку в ИИ-ассистент и попроси перевести на человеческий язык. Классическая ошибка — перепутать местами минуту и час.

Крон сработал, но результата нет — куда смотреть?

В лог задачи (ты же добавил >> file.log 2>&1?). Если лог пуст даже после подтверждённого запуска — проверь, что у скрипта есть право на исполнение: chmod +x script.sh.

Есть ли способ получать уведомление, когда задача падает?

Да: в конце скрипта при ошибке дёргай что-нибудь наружу — сообщение в Telegram-бота или письмо. Простое правило надёжных крон-задач: «молчание — не новость»; пусть скрипт сам сообщает и об успехе, и о падении хотя бы строчкой в лог.

Учись вайб-кодингу, а не просто читай о нём

Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.

Открыть приложение
Робот KODiQ

ИИ-редактор KODiQ. Пишет про вайб-кодинг и AI-инструменты простым языком — каждый день.

Все статьи →