Cron и crontab: запуск задач по расписанию с примерами

Cron — планировщик задач в Linux: он запускает команды и скрипты по расписанию, раз в минуту, каждый час, по понедельникам или после перезагрузки. Расписание хранится в crontab — таблице, где одна строка означает одну задачу. На нашем домашнем сервере по cron работают сторожа, которые присылают отчёты, чистка логов, обслуживание Docker, а один из сторожей по понедельникам проверяет ссылки в статьях этого сайта. Разберём синтаксис cron, команды crontab с примерами и почему задача, которая работает из консоли, не запускается по cron.

Задания crontab на сервере и запись о запуске в журнале cron
Настоящий crontab нашего сервера: сторожа, Nextcloud, чистка логов и Docker

Как устроена строка crontab

Пять полей времени, затем команда:

┌───────── минута (0–59)
│ ┌─────── час (0–23)
│ │ ┌───── день месяца (1–31)
│ │ │ ┌─── месяц (1–12)
│ │ │ │ ┌─ день недели (0–7, 0 и 7 — воскресенье)
│ │ │ │ │
5 9 * * * команда

* означает «любое значение». Строка выше — «в 9:05 каждый день». В полях можно писать:

  • */15 — каждые 15 единиц: каждые 15 минут, каждые 2 часа (*/2 в поле часа);
  • 1,15 — список значений;
  • 9-18 — диапазон;
  • 9-18/2 — каждые два часа с 9 до 18.

Проверить, правильно ли вы поняли расписание, удобно на crontab.guru: вставляете пять полей и получаете расшифровку словами и ближайшие запуски.

Cron: примеры расписаний

РасписаниеКогда запускается
* * * * *каждую минуту
*/5 * * * *каждые 5 минут
0 * * * *каждый час, в начале часа
0 3 * * *каждый день в 3:00
15 9 * * 1по понедельникам в 9:15
25 9-18 * * 1-5по будням каждый час с 9:25 до 18:25
0 3 1 * *первого числа каждого месяца в 3:00
@rebootодин раз после загрузки сервера
@daily, @weekly, @monthlyраз в день, неделю, месяц (в полночь)

Время — по часовому поясу сервера. Проверьте его командой timedatectl: на многих VPS по умолчанию стоит UTC, и «9 утра» наступит в полдень по Москве.

Команды crontab

crontab -l          # посмотреть свои задания
crontab -e          # редактировать
sudo crontab -l -u www-data   # задания другого пользователя

crontab -e открывает таблицу в текстовом редакторе. При первом запуске предложат выбрать редактор — проще всего nano. В nano сохранить — Ctrl+O и Enter, выйти — Ctrl+X. После выхода crontab проверит синтаксис и сообщит installing new crontab — значит, всё сохранилось. Редактировать сами файлы в /var/spool/cron/crontabs/ руками не нужно.

Осторожно с crontab -r: эта команда без вопросов удаляет всю таблицу, а на клавиатуре r соседствует с e. Перед экспериментами сохраните копию: crontab -l > ~/crontab-backup.txt.

Кроме личных таблиц есть системные: файлы в /etc/cron.d/ и /etc/crontab. У них между временем и командой есть шестое поле — имя пользователя, от которого запускать. Туда же пакеты кладут свои задания. Ещё есть папки /etc/cron.daily/, /etc/cron.weekly/ — скрипты из них запускаются раз в день или неделю.

Примеры задач с нашего сервера

# каждый день в 9:05 — сторож letweb.ru ищет поводы для новостей
5 9 * * * cd /opt/private/hosting/letweb && /usr/bin/python3 storozh_letweb.py povody >> /var/log/storozh_letweb.log 2>&1

# по понедельникам в 9:15 — проверка внешних ссылок в статьях
15 9 * * 1 cd /opt/private/hosting/letweb && /usr/bin/python3 storozh_letweb.py ssylki >> /var/log/storozh_letweb.log 2>&1

# каждые 5 минут — фоновые задачи Nextcloud внутри контейнера
*/5 * * * * docker exec -u www-data nextcloud-app php -f /var/www/html/cron.php >/dev/null 2>&1

# в 3:00 — удалить сжатые логи старше 30 дней
0 3 * * * find /var/log -name "*.gz" -mtime +30 -delete

# по воскресеньям в 4:00 — убрать неиспользуемые образы и контейнеры Docker
0 4 * * 0 docker system prune -f --volumes --filter "until=24h"

# раз в неделю — ужать системный журнал до 50 МБ
@weekly journalctl --vacuum-size=50M

Что тут важно:

  • >> файл.log 2>&1 — дописывать и обычный вывод, и ошибки в журнал. Без этого вы не узнаете, почему задача упала.
  • >/dev/null 2>&1 — выбросить вывод. Подходит для задач, которые запускаются часто и работают годами.
  • cd папка && — перейти в папку скрипта, если он ищет свои файлы рядом с собой.

Защита от двойного запуска

Если задача запускается каждые 5 минут, а иногда работает дольше, следующий запуск начнётся поверх предыдущего. Помогает flock — он не даст запустить вторую копию, пока работает первая:

*/15 * * * * /usr/bin/flock -n /tmp/moya-zadacha.lock /usr/bin/python3 /opt/skript.py

-n — если занято, просто пропустить этот запуск. Вместо него можно написать -w 300 — подождать до 5 минут.

Почему cron не запускает задачу

Самая частая жалоба: «из консоли скрипт работает, а по cron — нет». Причины почти всегда эти:

  1. Другое окружение. Cron запускает команды с минимальной переменной PATH и без ваших настроек из .bashrc. Пишите полные пути: /usr/bin/python3, а не python3. Где лежит программа, покажет which python3.
  2. Другая текущая папка. Скрипт запускается из домашней папки пользователя, а не из своей. Используйте cd папка && или абсолютные пути внутри скрипта.
  3. Знак %. В crontab % означает перевод строки. Команда date +%Y-%m-%d в cron сломается — пишите date +\%Y-\%m-\%d.
  4. Нет прав на запуск. Скрипт без chmod +x или без строки #!/bin/bash в начале. Надёжнее запускать через интерпретатор: /bin/bash /путь/скрипт.sh.
  5. Нет перевода строки в конце файла. Последняя строка crontab без перевода строки может быть проигнорирована.
  6. Переменные окружения. Токены и пароли, которые вы задали в консоли через export, cron не видит. Задайте их прямо в строке задания (КЛЮЧ=значение команда) или в файле, который читает сам скрипт.

Проверить, запускал ли cron задачу вообще:

grep CRON /var/log/syslog | tail          # Ubuntu и Debian с rsyslog
journalctl -u cron --since today            # где журнал ведёт systemd

Если в журнале запуск есть, а результата нет — ошибка в самом скрипте, и её покажет файл, куда вы направили вывод.

Что ещё можно поручить cron

  • ночные резервные копии сайта и базы;
  • проверку, что сайт отвечает, с уведомлением в Telegram;
  • обновление SSL-сертификатов — хотя certbot ставит свой таймер сам, об этом в статье бесплатный SSL-сертификат Let’s Encrypt;
  • ежедневную проверку сервера на руткиты и майнеры — мы добавили её после заражения одного из VPS;
  • обслуживание контейнеров, если сервисы запущены через Docker Compose.

Пример из жизни: фоновые задачи Nextcloud в Docker запускаются строкой в crontab каждые 5 минут — см. статью своё облачное хранилище.

Документация: crontab(5), flock(1). Проверено 26 сентября 2026 года.

13 / 1
Оцените статью
Да будет Интернет!