CRON — это одна из самых важных и полезных утилит в Linux, которая позволяет автоматизировать выполнение задач по расписанию. Без неё невозможно представить администрирование сервера: резервные копии, ротация логов, обновление кеша, отправка отчётов, мониторинг — всё это делается через CRON.
В этой статье мы подробно разберём:
- Что такое CRON и как он работает.
- Формат задания расписания (синтаксис crontab).
- Управление заданиями: crontab, системные cron-файлы.
- Примеры настройки для типовых задач.
- Особенности CRON в разных системах (Debian/Ubuntu, CentOS/RHEL).
- Обработка вывода и логирование.
- Распространённые ошибки и как их избежать.
- Отладка и мониторинг заданий.
- Альтернативы CRON (systemd timers).
1. Что такое CRON и зачем он нужен
CRON (от греческого «chronos» — время) — это демон (фоновый процесс) в Unix-подобных системах, который выполняет команды и скрипты по заданному расписанию. Он работает в фоновом режиме, проверяя каждую минуту, не настало ли время для выполнения какой-либо запланированной задачи.
Типичные задачи для CRON:
- Ежедневное резервное копирование файлов и баз данных.
- Ротация (архивация и удаление) старых логов.
- Обновление кеша или индекса поиска.
- Отправка отчётов по электронной почте.
- Проверка доступности сервисов и отправка оповещений.
- Синхронизация данных с внешними сервисами.
- Очистка временных файлов.
- Автоматическое обновление системы (критические патчи).
2. Как работает CRON
CRON работает следующим образом:
- Демон
crondзапускается при старте системы и работает постоянно. - Каждую минуту он просыпается и проверяет, есть ли задания, которые должны быть выполнены в эту минуту.
- Он считывает конфигурационные файлы:
- Системный crontab (
/etc/crontab). - Файлы в директории
/etc/cron.d/. - Пользовательские crontab (доступные через
crontab -e). - Вспомогательные директории для ежечасных, ежедневных и т.д. заданий (
/etc/cron.hourly/,/etc/cron.daily/,/etc/cron.weekly/,/etc/cron.monthly/).
- Системный crontab (
- Если находит совпадение по времени, он выполняет команду от имени указанного пользователя.
- Вывод команды (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 * * * * |
Пример:
@daily /usr/local/bin/backup.sh
4. Управление заданиями через crontab
4.1 Пользовательские задания
Каждый пользователь может иметь свой собственный crontab. Для управления используются команды:
# Редактирование 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. Пример:
*/5 * * * * wget -q -O - 'http://example.ru/wp-cron.php?doing_wp_cron' > /dev/null 2>&1
или с curl:
# ПРАВИЛЬНО: Обязательно оборачиваем URL в кавычки, чтобы CRON не сломал строку на спецсимволах, и задаем таймаут
*/5 * * * * curl -fsS --max-time 300 -o /dev/null 'https://example.ru/wp-cron.php?doing_wp_cron'
В wp-config.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:
# Формат: минута час день_месяца месяц день_недели пользователь команда
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
4.3 Переменные окружения в crontab
В crontab можно определять переменные окружения, которые будут доступны при выполнении заданий:
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@example.com # Куда отправлять вывод заданий
# Теперь все команды будут использовать эти настройки
0 2 * * * /usr/local/bin/backup.sh
Полезные переменные:
SHELL— оболочка, используемая для выполнения команд (по умолчанию/bin/sh).PATH— пути поиска исполняемых файлов.MAILTO— адрес, на который отправляется вывод заданий (если пусто — письма не отправляются).HOME— домашняя директория пользователя (может влиять на относительные пути).
⚠️ Не храните секреты в crontab. Никогда не пишите токены, пароли и ключи прямо в строке задания. Используйте переменные окружения или файлы с ограниченным доступом.
Пример безопасного подхода:
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
0 2 * * * /usr/local/bin/backup-to-s3.sh5. Настройка CRON в разных системах
5.1 Debian / Ubuntu
В Debian/Ubuntu CRON настраивается стандартным образом. Особенности:
- Системные задания находятся в
/etc/crontabи/etc/cron.d/. - Скрипты в
/etc/cron.daily/и аналогичных выполняются черезrun-parts(утилита, которая запускает все скрипты в директории). - По умолчанию используется демон
cron.
Установка и управление:
# CRON уже установлен по умолчанию, но если нет:
sudo apt install cron
# Запуск и автозагрузка
sudo systemctl start cron
sudo systemctl enable cron
# Проверка статуса
sudo systemctl status cron5.2 CentOS / RHEL / Rocky Linux
В системах на основе RHEL используется демон crond.
Установка и управление:
# Установка (обычно уже установлен)
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):
0 2 * * * root /usr/local/bin/backup.sh
Пользовательский crontab (crontab -e):
0 2 * * * /usr/local/bin/backup.sh
5.4 Альтернативы: Anacron
anacron — это дополнительный инструмент, который запускает задания, пропущенные из-за выключения сервера. В отличие от CRON, он не привязан к точному времени, а выполняет задачи с задержкой после запуска системы. Обычно используется для ежедневных/еженедельных заданий на ноутбуках или рабочих станциях.
В серверной среде Anacron часто не требуется, так как сервер работает круглосуточно.
6. Обработка вывода и логирование
6.1 Перенаправление вывода
По умолчанию CRON отправляет весь вывод (stdout и stderr) на электронную почту владельца задания (или на адрес в MAILTO), если в системе настроен MTA (sendmail/postfix/exim). Если почтовый агент не настроен, этот вывод будет молча сбрасываться или засорять системный буфер. В продакшене это может забить почтовый ящик, поэтому лучше перенаправлять вывод в файлы или отключать.
Перенаправление stdout и stderr в файл:
0 2 * * * /usr/local/bin/backup.sh > /var/log/backup.log 2>&1
Перенаправление только ошибок (stderr):
0 2 * * * /usr/local/bin/backup.sh 2>> /var/log/backup_errors.log
Отключение вывода (перенаправление в /dev/null):
0 2 * * * /usr/local/bin/backup.sh > /dev/null 2>&1
6.2 Логи CRON
Сам CRON пишет свои логи в системный журнал. Посмотреть их можно через:
# Через 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 Добавление логирования в скрипт
В сам скрипт полезно добавить логирование с датой:
#!/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. Пример:
/var/log/cron/*.log {
daily
rotate 7
compress
missingok
notifempty
create 0644 root root
}
Эти скрипты можно заменить на готовые инструменты из набора htaccess‑tools: конструктор sitemap, минификатор CSS/JS, проверка битых ссылок.
7. Распространённые ошибки и проблемы
7.1 Неправильный путь к файлу
Ошибка: Использование относительных путей в команде.
Решение: Всегда используйте абсолютные пути или задавайте PATH в crontab.
Пример ошибки:
0 2 * * * backup.sh # backup.sh не найдёт, если его нет в PATH
Правильно:
0 2 * * * /usr/local/bin/backup.sh
7.2 Отсутствие прав на выполнение
Ошибка: Скрипт не имеет права на выполнение.
Решение:
chmod +x /usr/local/bin/backup.sh7.3 Переменные окружения отсутствуют
Ошибка: В скрипте используются переменные окружения, которые не определены в cron.
Решение:
- Определите переменные в начале crontab или внутри скрипта.
- Или задайте
PATHявно.
Пример:
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
0 2 * * * /usr/local/bin/backup.sh
7.4 Неправильный синтаксис времени
Ошибка: Неправильный формат полей времени (например, * где не нужно или пропущенное поле).
Решение: Проверьте количество полей. В системном crontab — 5 полей расписания + поле пользователя перед командой, в пользовательском — 5 (без пользователя).
7.5 Маска для вывода слишком частая
Ошибка: Использование маски * * * * * (каждую минуту) для тяжёлых операций.
Решение: Оцените необходимость частоты. Если задача тяжёлая, используйте более редкое расписание или ставьте @hourly, @daily.
7.6 Использование % в команде
Ошибка: Символ % в команде интерпретируется как перевод строки.
Решение: Экранируйте % обратным слешем (\%).
Пример:
# ПРАВИЛЬНО: экранируем знаки процента обратным слэшем без лишних внешних кавычек
0 2 * * * /usr/bin/date +\%Y-\%m-\%d > /tmp/date.log
Пример с датой:
# ОШИБКА: первый % и всё после него уходит в stdin команды, а не в её аргументы
0 2 * * * date +%Y-%m-%d > /tmp/date.log
# ПРАВИЛЬНО: экранируем %
0 2 * * * date +\%Y-\%m-\%d > /tmp/date.log7.7 Пропуск задания из-за выключенного сервера
Ошибка: Если сервер выключен, задания не выполняются.
Решение: Для критических задач используйте Anacron (для системных заданий) или планируйте задания с учётом времени работы сервера.
7.8 Не отправляются письма
Ошибка: Вывод не отправляется по почте, хотя MAILTO задан.
Решение:
- Проверьте, установлен и настроен ли почтовый агент (например,
sendmailилиpostfix). - Проверьте, что
MAILTOуказан правильно и почтовый домен доступен. - Или просто перенаправьте вывод в файл, как описано выше.
7.9 Задание выполняется несколько раз
Ошибка: Задание запускается чаще, чем нужно, из-за дублирования строк в crontab.
Решение: Проверьте crontab на дубликаты: crontab -l. Убедитесь, что задание не добавлено и в системный crontab, и в пользовательский.
8. Отладка и мониторинг заданий
8.1 Проверка, выполняется ли задание
Проверьте логи CRON, как описано выше. Также можно добавить в скрипт запись в отдельный лог-файл.
8.2 Ручной запуск для проверки
Перед добавлением в CRON всегда запускайте скрипт вручную:
/usr/local/bin/backup.shЭто позволит проверить, что он работает корректно и не выводит ошибки.
8.3 Тестирование расписания
Есть онлайн-инструменты (например, сайт crontab.guru), которые визуализируют расписание. Но вы также можете просто подставить время и проверить логи.
8.4 Уведомления об ошибках
Настройте отправку уведомлений при ошибках:
0 2 * * * /usr/local/bin/backup.sh || echo "Backup failed!" | mail -s "Backup error" admin@example.com8.5 Использование специальных утилит для мониторинга
Для более серьёзного мониторинга можно использовать:
- Healthchecks.io — сервис для мониторинга периодических задач (задание отправляет HTTP-запрос, если выполнено).
- Nagios / Zabbix — системы мониторинга, которые могут проверять наличие свежих логов.
9. Альтернативы CRON: systemd timers
В современных системах с systemd есть встроенная альтернатива CRON — systemd timers. Они предлагают более гибкие возможности: точность до секунд, зависимость от других сервисов, управление через единую систему.
Пример создания таймера для ежедневного бэкапа:
Создайте сервисный файл /etc/systemd/system/backup.service:
[Unit]
Description=Daily backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
Создайте файл таймера /etc/systemd/system/backup.timer:
[Unit]
Description=Run backup daily at 2am
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
Запустите и включите таймер:
sudo systemctl daemon-reload
sudo systemctl enable backup.timer
sudo systemctl start backup.timerПроверка таймеров:
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:
# См. пункт 4.1 в статье вышеВ пользовательском crontab (crontab -e) добавьте:
# ПРАВИЛЬНО: Обязательно оборачиваем 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.
👤 Зарегистрируйтесь, чтобы добавить материал в закладки.
