К основному содержимому

Cron на Linux: настройка планировщика задач на VPS

VDS / VPS · 19.04.2026 · 6 мин чтения
Иллюстрация к статье «Cron на Linux: настройка планировщика задач на VPS»

Cron — демон планирования задач в Unix-системах, запускающий команды по расписанию. Используется для резервного копирования, отправки отчётов, обновления сертификатов SSL и любой автоматизации.

Синтаксис cron-записи

# ┌───────────── минуты (0-59)
# │ ┌─────────── часы (0-23)
# │ │ ┌───────── день месяца (1-31)
# │ │ │ ┌─────── месяц (1-12)
# │ │ │ │ ┌───── день недели (0=Sun, 6=Sat)
# │ │ │ │ │
# * * * * * команда

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

ВыражениеКогда выполняется
* * * * *Каждую минуту
0 * * * *Каждый час (в 00 минут)
0 3 * * *Каждый день в 03:00
0 3 * * 1Каждый понедельник в 03:00
0 0 1 * *Первое число каждого месяца
*/15 * * * *Каждые 15 минут
0 2,14 * * *В 02:00 и 14:00
@rebootПри каждой перезагрузке
@dailyРаз в сутки (= 0 0 * * *)

Управление crontab

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

# Посмотреть текущий crontab
crontab -l

# Удалить crontab
crontab -r

# Crontab для другого пользователя (root)
sudo crontab -u www-data -e

Практические примеры

># Бэкап базы данных каждые 6 часов
0 */6 * * * mysqldump -u root -pPASSWORD mydb > /backup/db_$(date +%Y%m%d_%H%M).sql

# Обновление Let's Encrypt сертификатов
0 3 * * * certbot renew --quiet

# Очистка логов старше 30 дней
0 4 * * * find /var/log/myapp -name "*.log" -mtime +30 -delete

# Запуск Python-скрипта и логирование вывода
*/30 * * * * /usr/bin/python3 /opt/scripts/sync.py >> /var/log/sync.log 2>&1

# Перезапуск сервиса в 05:00 каждое воскресенье
0 5 * * 0 systemctl restart myapp

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

># Cron имеет минимальное окружение — $PATH может не содержать нужные пути
# Всегда используйте полные пути к командам
/usr/bin/php, /usr/local/bin/wp и т.д.

# Или явно задайте PATH в начале crontab:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=admin@example.com  # отправлять ошибки на email
💡 Отладка cron: Добавьте 2>&1 >> /tmp/cron_debug.log к команде для захвата всего вывода. Если cron молчит при явной ошибке — скорее всего проблема с PATH или правами файла.

Синтаксис crontab

# Формат: MIN HOUR DOM MON DOW COMMAND
# MIN    = 0-59
# HOUR   = 0-23
# DOM    = 1-31 (день месяца)
# MON    = 1-12
# DOW    = 0-7  (день недели, 0 и 7 = воскресенье)

# Каждые 5 минут
*/5 * * * * /usr/local/bin/check.sh

# Каждый день в 3:30
30 3 * * * /usr/local/bin/backup.sh

# Каждый понедельник в 2:00
0 2 * * 1 /usr/local/bin/weekly-report.sh

# Первое число каждого месяца в полночь
0 0 1 * * /usr/local/bin/monthly-cleanup.sh

Логирование cron-заданий

# Перенаправление вывода в лог
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# Подавление вывода (без логов)
0 3 * * * /usr/local/bin/backup.sh > /dev/null 2>&1

Специальные значения

ЗначениеЭквивалент
@rebootПри запуске системы
@daily0 0 * * *
@weekly0 0 * * 0
@monthly0 0 1 * *
💡 Для критических задач используйте systemd timers — они имеют встроенный retry механизм и интеграцию с journald для логов.

Частые ошибки в cron-заданиях

Большинство «cron не работает» на самом деле cron отработал правильно — просто с неожиданным для автора скрипта окружением.

/bin/sh: 1: wp: not found

Cron запускает команды с минимальным PATH, который часто не включает директорию, где лежит нужная утилита (например, /usr/local/bin для WP-CLI). Используйте полный путь к бинарнику: узнать его можно командой which wp в обычной оболочке и подставить результат в crontab.

You (deploy) are not allowed to use this program (crontab)

Пользователь не входит в список /etc/cron.allow, при этом сам файл существует — если cron.allow присутствует, доступ к crontab получают только перечисленные в нём пользователи, остальные блокируются независимо от прав sudo. Добавьте имя пользователя в файл или используйте sudo crontab -u username -e от администратора.

flock: 456: Resource temporarily unavailable

Это не сбой, а защита от повторного запуска: предыдущий экземпляр задачи ещё не завершился и держит файл блокировки, поэтому новый запуск сразу выходит. Если это происходит регулярно — проблема в том, что задача выполняется дольше интервала расписания, а не в самой блокировке; разбирайтесь, почему предыдущий запуск не укладывается в срок, а не убирайте flock.

cron или systemd timer: сравнение

Параметрcronsystemd timer
ЛогированиеВручную в файлВстроено в journald
Повтор при сбоеНетЕсть (Restart=, OnFailure=)
Точность расписанияДо минутыДо секунды
Зависимости от других службНетЕсть (After=, Requires=)

Для простых периодических задач cron остаётся проще в настройке. Для задач с зависимостями от других служб или необходимостью автоповтора при сбое — см. создание systemd unit-файла.

Когда cron не подходит

Минимальный интервал cron — одна минута; для задач, которые должны выполняться раз в несколько секунд, нужен отдельный демон или systemd timer с OnUnitActiveSec=. Cron сам по себе не защищает от параллельного запуска одной и той же задачи — если предыдущий экземпляр ещё выполняется, а новый стартует по расписанию, они будут работать одновременно, конкурируя за одни и те же ресурсы, если явно не обернуть команду в flock, как в примере выше. Для задач, критичных к доставке результата (например, обязательная отправка отчёта), cron не даёт встроенного механизма ретраев — при сбое задача просто не выполнится до следующего запуска по расписанию.

Как проверить результат

Появление задачи в расписании ещё не значит, что она реально отработала — проверяйте факт выполнения отдельно:

# Убедиться, что cron вообще запускал задачу
grep CRON /var/log/syslog | grep "backup.sh" | tail -5

# Проверить код завершения последнего запуска
echo $?

# На системах с journald
journalctl -u cron --since "1 hour ago" | grep backup

Само по себе появление записи в логе означает только то, что cron запустил команду — не то, что она завершилась успешно. Явно логируйте код возврата внутри самого скрипта или добавьте MAILTO в crontab, чтобы получать письмо при ненулевом коде завершения.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке