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.sh
MAILTO — адрес для отправки вывода (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>&1
2>&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.sh
PATH
Команды вроде 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 или планировщики внутри приложений.