Top.Mail.Ru
КОНФИГУРАТОР Серверы
Сетевое оборудование
СХД
IP-телефоны IP-камеры Источники бесперебойного питания (ИБП) Комплектующие Готовые решения Серверы под задачу
О компании Купить в лизинг Блог Отзывы Доставка Гарантия Контакты Работа у нас Реквизиты Спецпредложения Игровые ПК на ISKRAPC Заявка в тех поддержку
Эксперты в подборе IT-оборудования

Планировщик задач Crontab: примеры настройки и синтаксис

27 февраля 2026
Планировщик задач Crontab: примеры настройки и синтаксис

Вы вздрагиваете от звонка мониторинга — диск забит логами, сервис лежит, клиенты шлют гневные письма. А ведь достаточно было одной строчки в crontab, чтобы ротация логов работала сама. Планировщик задач Linux — та штука, которая превращает хаос ручных операций в тихую автоматику. И crontab настройка занимает ровно столько времени, сколько нужно, чтобы заварить чай.

Crontab (от «cron table») — файл расписания для демона cron. Этот демон проверяет задачи раз в минуту и запускает то, что пора запустить. Корни инструмента уходят в 1975 год — он появился ещё в Unix V7. С тех пор cron стал стандартом для всех Unix-подобных систем: от Debian на домашнем сервере до RHEL в корпоративном ЦОДе.

Синтаксис crontab: пять полей и одна команда

Каждая строка в crontab — это расписание в формате «когда» + «что делать». Формат такой:

┌───────────── минута (0–59)

│ ┌───────────── час (0–23)

│ │ ┌───────────── день месяца (1–31)

│ │ │ ┌───────────── месяц (1–12)

│ │ │ │ ┌───────────── день недели (0–7, где 0 и 7 = воскресенье)

│ │ │ │ │

* * * * * /path/to/command

Звёздочка означает «любое значение». Запятая разделяет конкретные значения, дефис задаёт диапазон, косая черта — шаг. Комбинации тоже работают: 1-15/3 значит «каждый третий день с 1-го по 15-е». Разберём на живых примерах:

Расписание Что делает
30 2 * * * Запуск в 2:30 ночи ежедневно
0 */4 * * * Каждые 4 часа в :00
0 9 * * 1-5 В 9:00 по будням
15,45 * * * * В :15 и :45 каждого часа
0 0 1,15 * * В полночь 1-го и 15-го числа

Синтаксис лаконичен, но покрывает 95% задач. Выполнение скрипта по расписанию сводится к одной строке — без GUI, без мастеров настройки, без XML-конфигов.

Команды управления: -e, -l, -r

Работа с пользовательским crontab идёт через утилиту crontab:

  • crontab -e — открывает файл расписания в редакторе ($EDITOR). Утилита проверяет синтаксис перед сохранением, так что опечатка не сломает уже работающие задачи.
  • crontab -l — выводит текущий файл на экран. Удобно для быстрой проверки или экспорта: crontab -l > backup-crontab.txt.
  • crontab -r — удаляет весь файл расписания. Без подтверждения, без корзины. Будьте аккуратны.
  • crontab -u username -e — редактирование чужого crontab (нужен root). Полезно при настройке задач для сервисных учётных записей.

Есть ещё системный файл /etc/crontab — он отличается от пользовательского дополнительным полем username между расписанием и командой:

# /etc/crontab

0 3 * * * root /usr/local/bin/backup.sh

Здесь явно указано, от какого пользователя запускать задачу. В пользовательских crontab (через crontab -e) этого поля нет — задача запускается от имени владельца файла.

Cron молча игнорирует строки с ошибками синтаксиса в /etc/crontab, но crontab -e не даст сохранить файл с ошибкой. Две разных модели поведения — помните об этом.

@-алиасы: расписание для людей

Помимо пяти полей, cron поддерживает удобные сокращения. Они не дают ничего нового по функционалу, но экономят время и снижают риск ошибки:

Алиас Эквивалент Когда запускается
@reboot При загрузке системы
@hourly 0 * * * * В начале каждого часа
@daily 0 0 * * * В полночь
@weekly 0 0 * * 0 В полночь воскресенья
@monthly 0 0 1 * * В полночь 1-го числа
@yearly 0 0 1 1 * 1 января в полночь

@reboot — особенно полезная вещь. Запуск VPN-тоннеля, поднятие tmux-сессии, прогрев кэша после перезагрузки — всё это удобно вешать именно на этот алиас. В отличие от Windows Task Scheduler, где для аналогичного результата нужно пройти через мастер создания задачи, указать триггер, действие и условия — здесь всё умещается в одну строку. Кстати, crontab поддерживает запуск задач от имени конкретных пользователей через поле username в /etc/crontab — в Windows для этого нужно заводить отдельные учётные записи в планировщике и хранить пароли.

У @reboot есть нюанс: задача запускается в момент старта демона cron, а не в момент загрузки ядра. Если cron стартует раньше сетевого стека, Ваш скрипт не сможет обратиться к внешним сервисам. Для таких сценариев надёжнее использовать systemd-юниты с зависимостью After=network-online.target.

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

Cron запускает задачи в минимальном окружении. PATH будет отличаться от того, к чему Вы привыкли в интерактивном терминале. HOME может указывать не туда, куда ожидаете. Переменных из .bashrc и .bash_profile не будет вовсе — cron их не загружает. Частая ошибка — скрипт работает руками, но падает в cron. Причина почти всегда кроется в окружении.

Попробуйте сами: выполните env -i /bin/sh -c 'echo $PATH' и сравните с тем, что показывает echo $PATH в обычном терминале. Разница будет ощутимой — cron работает примерно в таких же спартанских условиях.

Решения два. Первое — прописывать полные пути к бинарникам внутри скриптов (/usr/bin/python3 вместо python3). Второе — задать PATH прямо в crontab:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

SHELL=/bin/bash

MAILTO=admin@example.com


0 3 * * * /opt/scripts/backup.sh

Переменная MAILTO — ещё одна полезная штука. По умолчанию cron отправляет весь stdout и stderr задачи на почту владельцу crontab. Если вывод не нужен, можно перенаправить его в /dev/null:

0 3 * * * /opt/scripts/backup.sh > /dev/null 2>&1

А если нужно получать только ошибки — перенаправьте только stdout:

0 3 * * * /opt/scripts/backup.sh > /dev/null

Так stderr всё ещё будет приходить на почту, а обычный вывод отбросится.

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

Теория без практики мертва. Вот набор задач, которые покрывают типичные сценарии:

Бэкап MySQL ежедневно в 2:00:

0 2 * * * /usr/bin/mysqldump -u backupuser -p'SecretPass' --all-databases | gzip > /backups/mysql/$(date +\%Y\%m\%d).sql.gz

Здесь есть нюанс с экранированием % через \% — cron интерпретирует символ процента как перевод строки. Всё, что стоит после первого неэкранированного %, попадёт на stdin команды, а не в аргументы. Это одна из тех ловушек, на которых спотыкаются даже опытные админы. Если бэкап-скрипт сложнее одной строки — вынесите логику в отдельный .sh-файл и вызывайте его из crontab. Так проще и отлаживать, и поддерживать. А чтобы сами бэкапы не стали слабым звеном, стоит заранее продумать выбор сервера для хранения резервных копий — от этого зависит, насколько быстро удастся восстановить данные в случае аварии.

Мониторинг свободного места, предупреждение при заполнении > 90%:

*/10 * * * * df -h / | awk 'NR==2 && int($5)>90 {print "DISK ALERT: "$5" used"}' | mail -s "Disk Warning" admin@example.com

Проверка каждые 10 минут — достаточный интервал, чтобы поймать стремительно растущий лог до того, как диск забьётся на 100%. Если хотите мониторить несколько точек монтирования, создайте отдельный скрипт с циклом по df и порогами для каждого раздела.

Очистка временных файлов старше 7 дней:

0 4 * * 0 find /tmp -type f -mtime +7 -delete

Запуск в 4 утра по воскресеньям — период минимальной нагрузки на большинстве серверов. Флаг -delete эффективнее конструкции с -exec rm, так как не порождает отдельный процесс на каждый файл.

Синхронизация файлов между серверами каждые 6 часов:

0 */6 * * * rsync -azq --delete /data/ backup-server:/data/

Отладка: когда задача не запускается

Задача добавлена, синтаксис верный, но ничего не происходит. Знакомая ситуация? Чаще всего проблема сидит в одном из пяти мест, и найти её можно за пару минут, если знать, куда смотреть.

Первый шаг — загляните в лог. На большинстве дистрибутивов cron пишет в /var/log/cron или /var/log/syslog. Быстрый способ проверить:

grep CRON /var/log/syslog | tail -20

Если cron вообще не упоминает Вашу задачу — значит, он её не видит. Проверьте, загрузился ли демон: systemctl status cron (или crond на CentOS/RHEL). Убедитесь, что Вы редактировали crontab нужного пользователя. Если Вы добавляли задачу через sudo crontab -e, она попала в crontab root'а, а не Вашего пользователя.

Если в логе видно, что cron запускает задачу, но результата нет — проблема в самом скрипте. Добавьте логирование вывода:

0 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1

Перенаправление 2>&1 критически важно — без него stderr улетит в почту (или в никуда, если MAILTO не настроен), и Вы никогда не узнаете, что именно сломалось.

Типичные причины, по которым cron-задачи молча падают:

  • Нет прав на выполнение. chmod +x script.sh — банально, но часто забывают.
  • Относительные пути. Cron запускает задачу из домашнего каталога пользователя. Если скрипт ожидает конкретную рабочую директорию — добавьте cd /path && ./script.sh.
  • Окружение. Уже обсуждали выше: PATH в cron минимальный. Используйте env -i /bin/bash -c 'your_command' для тестирования скрипта в похожих условиях.
  • Экранирование %. Если в команде есть % без обратного слэша — cron обрежет строку.

Проверяйте cron-задачи командой env -i /bin/bash -c 'command' — это эмулирует окружение cron без переменных пользователя.

Безопасность и конкурентный доступ

На продакшн-сервере crontab — потенциальная точка входа для атак. Если скомпрометированный пользователь может создавать cron-задачи, он способен запускать что угодно с периодичностью в минуту. Два инструмента помогают контролировать ситуацию: файлы доступа и блокировки.

Файлы cron.allow и cron.deny (лежат в /etc/) контролируют, кто вообще имеет право использовать crontab. Логика работы такая: если существует cron.allow — доступ есть только у перечисленных в нём пользователей, а cron.deny игнорируется. Если cron.allow нет, но есть cron.deny — заблокированы только указанные в нём. Если нет ни того, ни другого — поведение зависит от дистрибутива. В Debian доступ открыт всем, а в Red Hat и его производных — только root.

Рекомендация для продакшна: создайте cron.allow и добавьте туда только тех пользователей, которым crontab действительно нужен. Это лучше, чем пытаться перечислить всех «лишних» в cron.deny.

flock решает другую проблему — конкурентный запуск. Представьте: задача бэкапа выполняется 40 минут, а интервал запуска — 30 минут. Без защиты два экземпляра скрипта работают параллельно, пишут в один файл, дерутся за ресурсы. Результат — повреждённый бэкап и нагрузка на диск. Решение:

* * * * * /usr/bin/flock -n /tmp/myjob.lock /opt/scripts/heavy-task.sh

Флаг -n означает «не ждать, выйти сразу, если лок занят». Так второй экземпляр просто не запустится, пока первый работает. Есть и альтернативный режим — -w timeout, который ждёт указанное количество секунд и сдаётся, если лок не освободился. Для долгих задач с непредсказуемым временем выполнения -n безопаснее.

Альтернативные каталоги: cron.d, cron.daily и компания

Помимо пользовательских crontab-файлов, существует набор системных каталогов, и у каждого своя специфика:

  • /etc/cron.d/ — сюда кладут файлы в формате /etc/crontab (с полем username). Удобно для пакетов — при установке софт просто бросает свой файл сюда, при удалении — убирает. Каждый файл обрабатывается отдельно, так что ошибка в одном не затрагивает остальные.
  • /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/ — каталоги для скриптов, которые запускает run-parts. Здесь не нужен синтаксис crontab — достаточно положить исполняемый файл. Но есть подвох: имя файла не должно содержать точку. Скрипт backup.sh не запустится — run-parts пропускает файлы с расширениями. Назовите его просто backup или backup-db.

Тонкость: скрипты в cron.daily и подобных каталогах запускает не сам cron напрямую, а anacron (на десктопных системах) или запись в /etc/crontab. Время запуска настраивается в /etc/crontab или /etc/anacrontab. Anacron полезен для машин, которые не работают круглосуточно — он «подхватывает» пропущенные задачи после включения.

Cron vs systemd-таймеры: когда что использовать

На systemd-дистрибутивах (а это сейчас подавляющее число серверных ОС) есть альтернатива — systemd-таймеры. Они решают те же задачи, но с другими компромиссами:

Критерий cron systemd-таймеры
Сложность настройки Одна строка Два файла (.timer + .service)
Логирование /var/log/cron, MAILTO journalctl, встроенное
Зависимости Нет Можно указать зависимости от сервисов
Точность 1 минута До секунды, поддержка монотонных таймеров
Запуск пропущенных Только через anacron Встроенный Persistent=true
Управление ресурсами Нет cgroups, лимиты CPU/RAM через unit-файлы

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

Перевод задачи из cron в systemd выглядит так. Вместо строки 0 3 * * * /opt/scripts/backup.sh создаются два файла:

# /etc/systemd/system/backup.timer

[Unit]

Description=Daily backup timer


[Timer]

OnCalendar=*-*-* 03:00:00

Persistent=true


[Install]

WantedBy=timers.target

# /etc/systemd/system/backup.service

[Unit]

Description=Daily backup


[Service]

Type=oneshot

ExecStart=/opt/scripts/backup.sh

Затем systemctl enable --now backup.timer — и готово. Громоздко? Да. Зато journalctl -u backup.service покажет полный вывод задачи с временными метками, а systemctl list-timers — когда была последняя и следующая активация.

Полезные приёмы напоследок

Рандомная задержка. Если десять серверов одновременно ломятся на бэкап-хранилище в 3:00, пропускная способность делится на всех. NFS-шара стонет, rsync-сессии таймаутятся, а мониторинг рисует красные графики. Добавьте случайную задержку:

0 3 * * * sleep $((RANDOM \% 900)) && /opt/scripts/backup.sh

Это раскидает запуски по 15-минутному окну.

Логирование с временными метками. Голый >> в файл не покажет, когда задача выполнялась:

0 * * * * /opt/scripts/check.sh 2>&1 | while read line; do echo "$(date '+\%F \%T') $line"; done >> /var/log/check.log

Crontab под контролем версий. Храните эталонный crontab в Git и деплойте через crontab /path/to/crontab-file. Так Вы всегда знаете, кто и когда менял расписание. Ansible, Salt, Puppet — все умеют управлять crontab-записями, что логично для инфраструктуры с десятками серверов. При использовании Git удобно держать crontab-файлы рядом с самими скриптами — в одном репозитории и в одном ревью.

Онлайн-валидаторы. Если синтаксис cron-выражений вызывает сомнения — воспользуйтесь сервисами вроде crontab.guru. Вбиваете выражение, получаете расшифровку человеческим языком и список ближайших запусков. Экономит нервы, особенно при хитрых расписаниях с комбинацией диапазонов и шагов.

Cron — инструмент из 1975 года, который пережил контейнеры, облака и Kubernetes. В k8s есть CronJob, в systemd — таймеры, в облаках — Lambda и Cloud Scheduler. Но если у Вас стоит Linux-сервер и нужно запускать скрипт по расписанию — crontab настройка по-прежнему делает это за минуту, без зависимостей и оверхеда. Полвека — и ни одного лишнего абстрактного слоя. Для утилиты командной строки это, пожалуй, лучшая рекомендация из возможных.

ПОДПИСКА

НА РАССЫЛКУ
ПОЛЕЗНЫЕ СТАТЬИ, АКЦИИ
И ЗАКРЫТЫЕ РАСПРОДАЖИ
Котик подписка
Похожие статьи
Вам также может быть интересно

ТОП-5 ошибок при выборе сервера
Товар добавлен в список сравнения
Перейти в сравнение
Продолжить просмотр
Заявка в тех поддержку
Консультация
ИТ-специалиста
Перезвоним и ответим на ваши вопросы
или напишите нам
IT-архитектор подберет сервер под вашу задачу
Заказать сервер
Мы свяжемся с вами в течение 15 мин
Зарегистрироваться в бонусной программе
Консультация
ИТ-специалиста
Перезвоним и ответим на ваши вопросы
или напишите нам