Руководство по CRON: планировщик задач в Linux

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

В этой статье мы подробно разберём:

  • Что такое CRON и как он работает.
  • Формат задания расписания (синтаксис crontab).
  • Управление заданиями: crontab, системные cron-файлы.
  • Примеры настройки для типовых задач.
  • Особенности CRON в разных системах (Debian/Ubuntu, CentOS/RHEL).
  • Обработка вывода и логирование.
  • Распространённые ошибки и как их избежать.
  • Отладка и мониторинг заданий.
  • Альтернативы CRON (systemd timers).

1. Что такое CRON и зачем он нужен

CRON (от греческого «chronos» — время) — это демон (фоновый процесс) в Unix-подобных системах, который выполняет команды и скрипты по заданному расписанию. Он работает в фоновом режиме, проверяя каждую минуту, не настало ли время для выполнения какой-либо запланированной задачи.

Типичные задачи для CRON:

  • Ежедневное резервное копирование файлов и баз данных.
  • Ротация (архивация и удаление) старых логов.
  • Обновление кеша или индекса поиска.
  • Отправка отчётов по электронной почте.
  • Проверка доступности сервисов и отправка оповещений.
  • Синхронизация данных с внешними сервисами.
  • Очистка временных файлов.
  • Автоматическое обновление системы (критические патчи).

2. Как работает CRON

CRON работает следующим образом:

  1. Демон crond запускается при старте системы и работает постоянно.
  2. Каждую минуту он просыпается и проверяет, есть ли задания, которые должны быть выполнены в эту минуту.
  3. Он считывает конфигурационные файлы:
    • Системный crontab (/etc/crontab).
    • Файлы в директории /etc/cron.d/.
    • Пользовательские crontab (доступные через crontab -e).
    • Вспомогательные директории для ежечасных, ежедневных и т.д. заданий (/etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/).
  4. Если находит совпадение по времени, он выполняет команду от имени указанного пользователя.
  5. Вывод команды (stdout и stderr) по умолчанию отправляется по электронной почте владельцу задания (если настроен почтовый агент).

3. Синтаксис CRON (формат расписания)

Каждая строка в crontab имеет следующий формат:

3.1 Поля расписания

ПолеДиапазонОписание
Минута0–59Минута часа
Час0–23Час дня (0 = полночь)
День месяца1–31День месяца
Месяц1–12Месяц (или названия: jan, feb, …)
День недели0–7День недели (0 и 7 = воскресенье, 1 = понедельник, … или названия: sun, mon, …)
КомандаЛюбая команда или путь к скриптуКоманда, которая будет выполнена

3.2 Специальные символы

СимволЗначениеПример
*Любое значение (все возможные)* * * * * — каждую минуту
,Список значений1,15,30 * * * * — на 1-й, 15-й и 30-й минуте каждого часа
-Диапазон значений0-10 * * * * — с 0-й по 10-ю минуту каждого часа
/Шаг (каждые N)*/15 * * * * — каждые 15 минут
?Не используется (только в некоторых реализациях)—

3.3 Примеры расписаний

РасписаниеОписание
* * * * *Каждую минуту
*/5 * * * *Каждые 5 минут
0 * * * *Каждый час в 0 минут
0 2 * * *Каждый день в 2:00 ночи
0 0 * * 0Каждое воскресенье в полночь
0 0 1 * *Первого числа каждого месяца в полночь
*/15 9-17 * * 1-5Каждые 15 минут с 9:00 до 17:59 по рабочим дням
0 12 * * 1,3,5В понедельник, среду и пятницу в 12:00

3.4 Переменные и сокращения

В некоторых реализациях CRON поддерживают сокращения:

СокращениеРасшифровкаЭквивалент
@rebootПри запуске системы(один раз после перезагрузки)
@yearly / @annuallyЕжегодно0 0 1 1 *
@monthlyЕжемесячно0 0 1 * *
@weeklyЕженедельно0 0 * * 0
@daily / @midnightЕжедневно в полночь0 0 * * *
@hourlyЕжечасно0 * * * *

Пример:

4. Управление заданиями через crontab

4.1 Пользовательские задания

Каждый пользователь может иметь свой собственный crontab. Для управления используются команды:

Bash
# Редактирование crontab текущего пользователя
crontab -e

# Просмотр текущего crontab
crontab -l

# Удаление всех заданий текущего пользователя
crontab -r

# Редактирование crontab другого пользователя (только root)
sudo crontab -u username -e

# Просмотр crontab другого пользователя
sudo crontab -u username -l

При первом запуске crontab -e система спросит, какой редактор использовать (nano, vim, etc.).

⚠️ WordPress и CRON: wp-cron vs системный cron
В WordPress есть встроенный планировщик wp-cron.php, который запускается при каждом запросе к сайту. Это удобно, но плохо для нагруженных сайтов: нагрузка растёт, а задачи могут не выполняться, если нет трафика.

Как правильно: отключите автоматический запуск и вызывайте wp-cron через системный CRON. Пример:

Bash
*/5 * * * * wget -q -O - 'http://example.ru/wp-cron.php?doing_wp_cron' > /dev/null 2>&1

или с curl:

Bash
# ПРАВИЛЬНО: Обязательно оборачиваем URL в кавычки, чтобы CRON не сломал строку на спецсимволах, и задаем таймаут
*/5 * * * * curl -fsS --max-time 300 -o /dev/null 'https://example.ru/wp-cron.php?doing_wp_cron' 

В wp-config.php добавьте:

PHP
define('DISABLE_WP_CRON', true);

Так задачи будут выполняться строго по расписанию, а не «когда кто‑то зайдёт на сайт».

4.2 Системные задания

Системные задания обычно размещаются в:

  • /etc/crontab — основной системный файл (только для root).
  • /etc/cron.d/ — директория для дополнительных системных заданий (каждый файл содержит задания в том же формате).
  • /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/ — директории для скриптов, которые выполняются с соответствующей периодичностью. Скрипты должны быть исполняемыми (chmod +x).

Пример содержимого /etc/crontab:

4.3 Переменные окружения в crontab

В crontab можно определять переменные окружения, которые будут доступны при выполнении заданий:

Полезные переменные:

  • SHELL — оболочка, используемая для выполнения команд (по умолчанию /bin/sh).
  • PATH — пути поиска исполняемых файлов.
  • MAILTO — адрес, на который отправляется вывод заданий (если пусто — письма не отправляются).
  • HOME — домашняя директория пользователя (может влиять на относительные пути).

⚠️ Не храните секреты в crontab. Никогда не пишите токены, пароли и ключи прямо в строке задания. Используйте переменные окружения или файлы с ограниченным доступом.
Пример безопасного подхода:

Bash
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
0 2 * * * /usr/local/bin/backup-to-s3.sh

5. Настройка CRON в разных системах

5.1 Debian / Ubuntu

В Debian/Ubuntu CRON настраивается стандартным образом. Особенности:

  • Системные задания находятся в /etc/crontab и /etc/cron.d/.
  • Скрипты в /etc/cron.daily/ и аналогичных выполняются через run-parts (утилита, которая запускает все скрипты в директории).
  • По умолчанию используется демон cron.

Установка и управление:

Bash
# CRON уже установлен по умолчанию, но если нет:
sudo apt install cron

# Запуск и автозагрузка
sudo systemctl start cron
sudo systemctl enable cron

# Проверка статуса
sudo systemctl status cron

5.2 CentOS / RHEL / Rocky Linux

В системах на основе RHEL используется демон crond.

Установка и управление:

Bash
# Установка (обычно уже установлен)
sudo dnf install cronie

# Запуск и автозагрузка
sudo systemctl start crond
sudo systemctl enable crond

# Проверка статуса
sudo systemctl status crond

Особенности:

  • Системный crontab — /etc/crontab.
  • Директории: /etc/cron.d/, /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/ (аналогично Debian).
  • В CentOS 7+ используется cronie (форк Vixie-cron).

5.3 Сравнение синтаксиса

В большинстве дистрибутивов синтаксис crontab идентичен. Единственное отличие — в системном /etc/crontab (и файлах в /etc/cron.d/) обязательно указывается пользователь, от имени которого выполняется команда. В пользовательском crontab (через crontab -e) поле пользователя отсутствует.

Системный crontab (/etc/crontab):

Пользовательский crontab (crontab -e):

5.4 Альтернативы: Anacron

anacron — это дополнительный инструмент, который запускает задания, пропущенные из-за выключения сервера. В отличие от CRON, он не привязан к точному времени, а выполняет задачи с задержкой после запуска системы. Обычно используется для ежедневных/еженедельных заданий на ноутбуках или рабочих станциях.

В серверной среде Anacron часто не требуется, так как сервер работает круглосуточно.

6. Обработка вывода и логирование

6.1 Перенаправление вывода

По умолчанию CRON отправляет весь вывод (stdout и stderr) на электронную почту владельца задания (или на адрес в MAILTO), если в системе настроен MTA (sendmail/postfix/exim). Если почтовый агент не настроен, этот вывод будет молча сбрасываться или засорять системный буфер. В продакшене это может забить почтовый ящик, поэтому лучше перенаправлять вывод в файлы или отключать.

Перенаправление stdout и stderr в файл:

Перенаправление только ошибок (stderr):

Отключение вывода (перенаправление в /dev/null):

6.2 Логи CRON

Сам CRON пишет свои логи в системный журнал. Посмотреть их можно через:

Bash
# Через journalctl (systemd)
journalctl -u cron   # Debian/Ubuntu
journalctl -u crond  # CentOS/RHEL

# Или через системный лог
grep CRON /var/log/syslog     # Debian/Ubuntu
grep CRON /var/log/cron       # CentOS/RHEL (иногда /var/log/messages)

Логи CRON показывают, когда запускалось задание, с каким PID и какой был код возврата.

6.3 Добавление логирования в скрипт

В сам скрипт полезно добавить логирование с датой:

Bash
#!/bin/bash
# backup.sh

LOG_FILE="/var/log/backup.log"
echo "$(date): Starting backup" >> $LOG_FILE
# ... команды бэкапа ...
if [ $? -eq 0 ]; then
    echo "$(date): Backup completed successfully" >> $LOG_FILE
else
    echo "$(date): Backup FAILED" >> $LOG_FILE
fi

Разделяйте логи по задачам. Не складывайте всё в один /var/log/backup.log. Лучше: /var/log/cron/backup-daily.log, /var/log/cron/sitemap-generate.log и т.п. Так проще искать проблему. Проверяйте ротацию. Если логи не ротировать, они быстро займут место на VPS. Пример:

Эти скрипты можно заменить на готовые инструменты из набора htaccess‑tools: конструктор sitemap, минификатор CSS/JS, проверка битых ссылок.

7. Распространённые ошибки и проблемы

7.1 Неправильный путь к файлу

Ошибка: Использование относительных путей в команде.

Решение: Всегда используйте абсолютные пути или задавайте PATH в crontab.

Пример ошибки:

Правильно:

7.2 Отсутствие прав на выполнение

Ошибка: Скрипт не имеет права на выполнение.

Решение:

Bash
chmod +x /usr/local/bin/backup.sh

7.3 Переменные окружения отсутствуют

Ошибка: В скрипте используются переменные окружения, которые не определены в cron.

Решение:

  • Определите переменные в начале crontab или внутри скрипта.
  • Или задайте PATH явно.

Пример:

7.4 Неправильный синтаксис времени

Ошибка: Неправильный формат полей времени (например, * где не нужно или пропущенное поле).

Решение: Проверьте количество полей. В системном crontab — 5 полей расписания + поле пользователя перед командой, в пользовательском — 5 (без пользователя).

7.5 Маска для вывода слишком частая

Ошибка: Использование маски * * * * * (каждую минуту) для тяжёлых операций.

Решение: Оцените необходимость частоты. Если задача тяжёлая, используйте более редкое расписание или ставьте @hourly, @daily.

7.6 Использование % в команде

Ошибка: Символ % в команде интерпретируется как перевод строки.

Решение: Экранируйте % обратным слешем (\%).

Пример:

Пример с датой:

Bash
# ОШИБКА: первый % и всё после него уходит в stdin команды, а не в её аргументы
0 2 * * * date +%Y-%m-%d > /tmp/date.log

# ПРАВИЛЬНО: экранируем %
0 2 * * * date +\%Y-\%m-\%d > /tmp/date.log

7.7 Пропуск задания из-за выключенного сервера

Ошибка: Если сервер выключен, задания не выполняются.

Решение: Для критических задач используйте Anacron (для системных заданий) или планируйте задания с учётом времени работы сервера.

7.8 Не отправляются письма

Ошибка: Вывод не отправляется по почте, хотя MAILTO задан.

Решение:

  • Проверьте, установлен и настроен ли почтовый агент (например, sendmail или postfix).
  • Проверьте, что MAILTO указан правильно и почтовый домен доступен.
  • Или просто перенаправьте вывод в файл, как описано выше.

7.9 Задание выполняется несколько раз

Ошибка: Задание запускается чаще, чем нужно, из-за дублирования строк в crontab.

Решение: Проверьте crontab на дубликаты: crontab -l. Убедитесь, что задание не добавлено и в системный crontab, и в пользовательский.

8. Отладка и мониторинг заданий

8.1 Проверка, выполняется ли задание

Проверьте логи CRON, как описано выше. Также можно добавить в скрипт запись в отдельный лог-файл.

8.2 Ручной запуск для проверки

Перед добавлением в CRON всегда запускайте скрипт вручную:

Bash
/usr/local/bin/backup.sh

Это позволит проверить, что он работает корректно и не выводит ошибки.

8.3 Тестирование расписания

Есть онлайн-инструменты (например, сайт crontab.guru), которые визуализируют расписание. Но вы также можете просто подставить время и проверить логи.

8.4 Уведомления об ошибках

Настройте отправку уведомлений при ошибках:

Bash
0 2 * * * /usr/local/bin/backup.sh || echo "Backup failed!" | mail -s "Backup error" admin@example.com

8.5 Использование специальных утилит для мониторинга

Для более серьёзного мониторинга можно использовать:

  • Healthchecks.io — сервис для мониторинга периодических задач (задание отправляет HTTP-запрос, если выполнено).
  • Nagios / Zabbix — системы мониторинга, которые могут проверять наличие свежих логов.

9. Альтернативы CRON: systemd timers

В современных системах с systemd есть встроенная альтернатива CRON — systemd timers. Они предлагают более гибкие возможности: точность до секунд, зависимость от других сервисов, управление через единую систему.

Пример создания таймера для ежедневного бэкапа:

Создайте сервисный файл /etc/systemd/system/backup.service:

Создайте файл таймера /etc/systemd/system/backup.timer:

Запустите и включите таймер:

Bash
sudo systemctl daemon-reload
sudo systemctl enable backup.timer
sudo systemctl start backup.timer

Проверка таймеров:

Bash
systemctl list-timers

Преимущества systemd timers:

  • Единое управление с другими службами.
  • Лучшая интеграция с журналом (journald).
  • Возможность запуска по условиям (например, только если сеть доступна).
  • Более точное планирование (вплоть до секунд).

Недостатки:

  • Требует systemd (не везде есть).
  • Немного сложнее синтаксис для новичков.
  • Меньше документации по сравнению с CRON.

Для большинства задач на VPS (бэкапы, генерация файлов, очистка кэша) CRON остаётся самым простым и понятным решением. systemd timers дают больше гибкости, но требуют более глубокого понимания systemd и не всегда нужны на типовых проектах.

10. WP‑cron и системный CRON

WordPress использует свой планировщик задач (wp-cron.php), который срабатывает при каждом просмотре страницы. Это удобно для небольших сайтов, но на проектах с высокой нагрузкой приводит к лишнему расходу ресурсов и нестабильному выполнению задач.

Рекомендуемый подход: отключить автоматический запуск и вызывать wp-cron по расписанию через системный CRON.

В файле wp-config.php:

PHP
# См. пункт 4.1 в статье выше

В пользовательском crontab (crontab -e) добавьте:

Bash
# ПРАВИЛЬНО: Обязательно оборачиваем URL в кавычки, чтобы CRON не сломал строку на спецсимволах, и задаем таймаут
*/5 * * * * curl -fsS --max-time 300 -o /dev/null 'https://example.ru/wp-cron.php?doing_wp_cron' 

Проверьте, что URL доступен и отдаёт HTTP 200, например, через ваш инструмент проверки URL или плагин SEO‑аудитора. Такой подход гарантирует, что запланированные задачи (рассылка, очистка кэша, генерация отчётов) будут выполняться строго по расписанию.

11. Заключение

Мы подробно разобрали планировщик CRON — один из самых важных инструментов в арсенале системного администратора. Вы узнали:

  • Что такое CRON и как он работает.
  • Как читать и создавать расписания с помощью синтаксиса crontab.
  • Как управлять заданиями через crontab и системные файлы.
  • Особенности настройки в разных дистрибутивах.
  • Как обрабатывать вывод и логировать выполнение.
  • Какие ошибки чаще всего возникают и как их избежать.
  • Как отлаживать и мониторить задания.
  • О существовании альтернативы — systemd timers.

👤 Зарегистрируйтесь, чтобы добавить материал в закладки.