cron
Планировщик задач (демон) — автоматическое выполнение команд по расписанию
Описание
cron — системный демон, запускающий задачи по заданному расписанию. Название происходит от греческого «хронос» (время). Демон работает постоянно в фоновом режиме и каждую минуту проверяет таблицы расписания (crontab), запуская команды, время которых наступило. Впервые реализован в AT&T Unix в 1970-х, современная реализация — Vixie cron (Пол Викси, 1988), используемая в большинстве Linux-дистрибутивов.
Демон cron читает расписание из нескольких источников: пользовательские crontab-файлы (/var/spool/cron/crontabs/), системный /etc/crontab, и файлы в директориях /etc/cron.d/, /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/. Системный crontab имеет дополнительное поле пользователя.
Как правило, администратор не взаимодействует с демоном cron напрямую — управление расписанием происходит через команду crontab. Прямые опции демона используются при его ручном запуске или в нестандартных конфигурациях. Для проверки состояния используй systemctl status cron (или crond на RHEL/CentOS).
Синтаксис и формат crontab
Структура строки crontab
0–59
0–23
1–31
1–12
0–7 (0,7=вс)
Спецсимволы в полях расписания
*— любое значение (каждую минуту/час/день…),— список значений:1,15,30— в 1, 15 и 30 минуту-— диапазон:9-17— с 9 до 17 часов/— шаг:*/15— каждые 15 минут;0-23/2— каждые 2 часа
Флаги демона cron
| Флаг | Описание |
|---|---|
-f | Foreground mode: не уходить в фон (daemon). Используется при запуске через systemd или supervisord, где демон должен оставаться на переднем плане |
-l | Включить syslog-логирование каждой запущенной задачи (по умолчанию отключено в некоторых версиях) |
-L LEVEL | Уровень детализации лога: 0 — нет логов; 1 — логировать запущенные задания; 2 — логировать каждое чтение crontab; 4 — логировать каждый crontab-тест; 8 — логировать pid процессов |
-n | Не перезапускать задачи, которые не завершились до следующего запланированного времени (no fork for mail). Актуально для long-running задач |
-i | Игнорировать /etc/cron.deny и /etc/cron.allow — позволить всем пользователям использовать crontab |
-s | Включить поддержку SELinux контекстов при запуске заданий (если cron собран с поддержкой SELinux) |
-m CMD | Использовать CMD вместо sendmail для отправки вывода заданий по email. Например: -m /usr/bin/mail |
-M | Не отправлять email — игнорировать вывод задания (useful для verbose cron jobs без email) |
-x FLAGS | Отладочные флаги (misc,io,load,pars,sch,proc,pnt,bit,ext,lst,detail). Только для разработки cron |
Паттерны использования
Управление демоном cron
# Проверить статус (systemd-системы) systemctl status cron # Debian/Ubuntu systemctl status crond # RHEL/CentOS/Fedora # Перезапустить после изменения конфига systemctl restart cron # Включить автозапуск при старте systemctl enable cron # Просмотр логов cron journalctl -u cron -f grep CRON /var/log/syslog | tail -20
Примеры расписания
# Каждые 5 минут */5 * * * * /usr/bin/check.sh # В 3:30 ночи каждый день 30 3 * * * /usr/bin/backup.sh # По рабочим дням в 9:00 0 9 * * 1-5 /usr/bin/report.sh # 1-го числа каждого месяца 0 0 1 * * /usr/bin/monthly.sh # Каждый час с 8 до 20 0 8-20 * * * /usr/bin/poll.sh # Пн, Ср, Пт в 12:00 0 12 * * 1,3,5 /usr/bin/sync.sh
Системный /etc/crontab
# /etc/crontab — требует поле USER SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin # MIN HOUR DOM MON DOW USER COMMAND 17 * * * * root cd / && run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || run-parts /etc/cron.daily 47 6 * * 7 root test -x /usr/sbin/anacron || run-parts /etc/cron.weekly 52 6 1 * * root test -x /usr/sbin/anacron || run-parts /etc/cron.monthly
Перенаправление вывода
# Подавить вывод полностью */5 * * * * /usr/bin/job.sh >/dev/null 2>&1 # Логировать только ошибки */5 * * * * /usr/bin/job.sh >>/var/log/job.log 2>&1 # Раздельные файлы для stdout и stderr */5 * * * * /usr/bin/job.sh \ 1>>/var/log/job.out \ 2>>/var/log/job.err # MAILTO="" — отключить email для одной задачи MAILTO="" */5 * * * * /usr/bin/silent-job.sh
Переменные окружения в crontab
# Переменные задаются в начале crontab SHELL=/bin/bash PATH=/usr/local/bin:/usr/bin:/bin MAILTO=admin@example.com HOME=/root # Важно: cron не загружает ~/.bashrc или ~/.profile # Всегда используй абсолютные пути к командам 0 2 * * * /usr/local/bin/python3 /opt/scripts/etl.py 0 3 * * * /usr/bin/pg_dump mydb > /backups/db_$(date +\%Y\%m\%d).sql
Скрипт в /etc/cron.d/
# /etc/cron.d/myapp — системный cron для приложения # Файл должен принадлежать root и не быть исполняемым # chmod 644 /etc/cron.d/myapp SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin # MIN HOUR DOM MON DOW USER COMMAND 0 */4 * * * www-data /opt/myapp/manage.py clearsessions 30 1 * * * www-data /opt/myapp/manage.py dbbackup
Советы и предупреждения
Задачи cron выполняются в минимальном окружении — без
~/.bashrc, ~/.profile, ~/.bash_profile. Переменная PATH обычно равна /usr/bin:/bin. Всегда используй абсолютные пути к командам (/usr/bin/python3, а не просто python3) или задавай PATH в начале crontab-файла.
Если задача может выполняться дольше интервала запуска, используй
flock для блокировки: */5 * * * * flock -n /tmp/job.lock /usr/bin/job.sh. Это предотвратит накопление параллельных процессов. Альтернатива — run-one.
Символ
% в crontab имеет специальное значение — он интерпретируется как перевод строки и начало stdin. Если команда содержит % (например, date +%Y-%m-%d), его необходимо экранировать обратным слешем: date +\%Y-\%m-\%d.
Cron использует локальное системное время сервера. При переходе на летнее/зимнее время задачи могут быть пропущены или запущены дважды. На серверах рекомендуется использовать UTC:
timedatectl set-timezone UTC. Для более предсказуемого планирования рассмотри anacron (запускает пропущенные задачи) или systemd timers.