Cron — стандартный планировщик задач в Unix-системах. Он выполняет команды по расписанию: бэкапы, рассылки, очистку логов, синхронизацию данных. Понимание синтаксиса и особенностей cron критично для надёжной автоматизации. В этом руководстве разберём все аспекты: от базового синтаксиса до отладки и продакшен-практик. Для генерации расписаний используйте Cron Generator на reChecker.
Что такое cron
Cron — демон, работающий в фоне и проверяющий таблицу заданий (crontab) каждую минуту. Когда время совпадает с расписанием, выполняется указанная команда. Cron не перезапускает задачи при перезагрузке — он всегда активен в системе.
Типичные сценарии:
- Резервное копирование баз данных и файлов
- Отправка отчётов и уведомлений
- Очистка временных файлов и логов
- Синхронизация данных между системами
- Запуск скриптов мониторинга и проверок
Синтаксис crontab
Строка задания состоит из пяти полей времени и команды:
* * * * * команда
│ │ │ │ │
│ │ │ │ └── день недели (0-7, 0 и 7 = воскресенье)
│ │ │ └──── месяц (1-12)
│ │ └────── день месяца (1-31)
│ └──────── час (0-23)
└────────── минута (0-59)Примеры базовых расписаний
| Расписание | Значение |
|---|---|
* * * * * | Каждую минуту |
0 * * * * | В начале каждого часа |
0 0 * * * | Каждый день в полночь |
0 9 * * 1-5 | В 9:00 по будням |
30 14 1 * * | 1-го числа каждого месяца в 14:30 |
0 0 1 1 * | 1 января в полночь |
Специальные значения
Звёздочка * — любое допустимое значение. * в поле «минута» означает «каждую минуту».
Запятая , — перечисление значений:
0 8,12,18 * * * # В 8:00, 12:00 и 18:00Дефис - — диапазон:
0 9-17 * * 1-5 # Каждый час с 9 до 17 по буднямСлэш / — шаг:
*/5 * * * * # Каждые 5 минут
0 */2 * * * # Каждые 2 часа
0 0 */3 * * # Каждые 3 дня в полночьКомбинации:
5,35 8-18 * * 1-5 # В 8:05, 8:35, 9:05, 9:35... с 8 до 18 по будням
0 0 1,15 * * # 1-го и 15-го числа в полночьИменованные значения (не везде)
Некоторые реализации cron поддерживают мнемоники:
@reboot # При загрузке системы
@yearly # 0 0 1 1 * (раз в год)
@monthly # 0 0 1 * * (раз в месяц)
@weekly # 0 0 * * 0 (раз в неделю)
@daily # 0 0 * * * (раз в день)
@hourly # 0 * * * * (раз в час)Проверьте поддержку в вашей системе: man crontab.
Редактирование crontab
# Редактировать задания текущего пользователя
crontab -e
# Просмотр текущих заданий
crontab -l
# Удалить все задания
crontab -r
# Загрузить задания из файла
crontab cronfile.txt
# Задания другого пользователя (требуются права)
crontab -u www-data -eПри crontab -e открывается редактор из переменной EDITOR или VISUAL. Сохранение и выход применяют изменения — перезапуск cron не нужен.
Переменные окружения
Cron запускает команды в минимальном окружении. Часто отсутствуют PATH, HOME и переменные из .bashrc. Явно задайте необходимое в начале crontab:
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@example.com
HOME=/home/user
0 0 * * * /opt/scripts/backup.shMAILTO — адрес для отправки вывода (stdout/stderr) по почте. Пустое значение отключает рассылку.
Часовые пояса
По умолчанию cron использует системный часовой пояс. Для задания своего:
CRON_TZ=Europe/Moscow
0 9 * * * /opt/scripts/report.shИли установите TZ в переменных окружения crontab. Убедитесь, что система знает нужную зону: ls /usr/share/zoneinfo/.
Перенаправление вывода
Без настройки cron отправляет вывод на почту (если указан MAILTO) или в syslog. Для записи в файл:
0 0 * * * /opt/backup.sh >> /var/log/backup.log 2>&12>&1 перенаправляет stderr в stdout. Для разделения:
0 0 * * * /opt/backup.sh >> /var/log/backup.log 2>> /var/log/backup.errПолное подавление вывода:
0 0 * * * /opt/backup.sh > /dev/null 2>&1Типичные ошибки
Относительные пути
Cron запускает команды из домашней директории пользователя (часто /home/user). Используйте абсолютные пути:
# Неправильно
0 0 * * * ./script.sh
# Правильно
0 0 * * * /home/user/scripts/backup.shPATH
Команды вроде node, php, python3 могут быть недоступны, если PATH не задан:
PATH=/usr/local/bin:/usr/bin:/bin
0 * * * * node /opt/app/cron.jsИли укажите полный путь: /usr/bin/node.
Права на выполнение
Скрипт должен иметь право на выполнение: chmod +x script.sh. Для интерпретаторов можно вызывать явно:
0 0 * * * /usr/bin/python3 /opt/scripts/task.pyБлокировка повторного запуска
Если задача выполняется дольше интервала, возможны параллельные запуски. Используйте lockfile:
#!/bin/bash
LOCKFILE=/tmp/backup.lock
if [ -f "$LOCKFILE" ]; then
exit 1
fi
trap "rm -f $LOCKFILE" EXIT
touch $LOCKFILE
# ... основная логикаИли flock:
0 * * * * flock -n /tmp/backup.lock /opt/backup.sh-n — не ждать, выйти с ошибкой при занятой блокировке.
Логирование и отладка
Включите логирование в скрипте:
#!/bin/bash
log() { echo "$(date '+%Y-%m-%d %H:%M:%S') $*" >> /var/log/cron-task.log; }
log "Starting"
# ...
log "Finished"Проверьте логи cron (дистрибутив-зависимо):
# Debian/Ubuntu
grep CRON /var/log/syslog
# CentOS/RHEL
grep CRON /var/log/cronТестовый запуск вручную с окружением cron:
env -i HOME=$HOME PATH=/usr/bin:/bin SHELL=/bin/bash /opt/script.shБезопасность
- Минимальные права — создайте отдельного пользователя для cron-задач с ограниченными правами
- Валидация входных данных — скрипты не должны доверять переменным окружения без проверки
- Секреты — не храните пароли в crontab; используйте конфиг-файлы с ограниченными правами (chmod 600)
- Аудит — регулярно проверяйте
crontab -lна подозрительные задания
Альтернативы cron
- systemd timers — интеграция с systemd, более гибкое логирование
- at — разовое выполнение в заданное время
- anacron — для систем, не работающих 24/7 (ноутбуки, десктопы)
Для веб-проектов часто используют внутренние планировщики: Laravel Scheduler, Celery Beat, Sidekiq Cron. Они удобнее для приложений, но требуют постоянно работающего процесса.
Практические примеры cron для веб-разработчиков — в статье 15 полезных cron-задач для веб-разработчика. Генерировать и проверять расписания можно в Cron Generator на reChecker.
Конфликты времени и cron
Cron запускает задачи в системном времени. Если сервер в UTC, а бизнес-логика ориентирована на локальное время (например, Москва), нужно учитывать разницу. Используйте CRON_TZ или переменную TZ в crontab:
CRON_TZ=Europe/Moscow
0 9 * * 1-5 /opt/send-report.shЗадача выполнится в 9:00 по Москве. Для скриптов, которые сами работают с датами, убедитесь, что они используют правильную временную зону или получают её из переменных окружения.
Уведомления об ошибках
Без настройки cron отправляет вывод на почту (если указан MAILTO) или теряет его. Для алертов при ошибках добавьте проверку exit code:
#!/bin/bash
/opt/backup.sh
if [ $? -ne 0 ]; then
echo "Backup failed" | mail -s "Cron alert" admin@example.com
exit 1
fiИли используйте ||:
0 3 * * * /opt/backup.sh || echo "Backup failed" | mail -s "Alert" admin@example.comЛогирование в cron
Стандартный подход — перенаправление в файл с датой:
0 0 * * * /opt/daily.sh >> /var/log/daily_$(date +\%Y\%m\%d).log 2>&1Для ротации логов используйте logrotate или встроенную логику в скрипте (удаление файлов старше N дней).
Cron и права
Задания выполняются от имени пользователя, которому принадлежит crontab. Для веб-приложений часто используют пользователя www-data или nginx. Убедитесь, что у пользователя есть права на чтение скриптов и запись в нужные директории:
# Проверка прав
ls -la /opt/scripts/backup.sh
# Должен быть исполняем для владельца или группы
chmod 750 /opt/scripts/backup.shВзаимодействие с systemd
В системах с systemd cron и systemd timers могут сосуществовать. Timers предлагают более гибкое логирование и интеграцию с journald. Для миграции cron-задачи в systemd:
# /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.targetРезюме
Cron остаётся простым и надёжным инструментом для периодических задач. Ключевые моменты: абсолютные пути, явный PATH, lockfile для длительных задач, логирование и мониторинг ошибок. Для сложных сценариев рассмотрите systemd timers или планировщики внутри приложений.