Back

Шпаргалка по Linux Cron

Шпаргалка по Linux Cron

Вы развернули своё Node-приложение на Linux-сервере и вам нужно, чтобы скрипт запускался каждую ночь в 3 часа утра. Вы слышали о cron, но синтаксис выглядит загадочно, а найденные руководства либо устарели, либо полны неточностей. Эта шпаргалка по Linux cron даёт вам корректный справочник с учётом особенностей дистрибутивов, необходимый для надёжного планирования cron-задач.

Ключевые моменты

  • Cron использует формат из пяти полей (минута, час, день месяца, месяц, день недели), за которыми следует команда для выполнения.
  • Когда указаны и день месяца, и день недели, cron обрабатывает их как ИЛИ, а не И — это распространённый источник неожиданного поведения.
  • Cron работает с ограниченным окружением, зависящим от дистрибутива, поэтому всегда используйте абсолютные пути и явно устанавливайте PATH для переносимости.
  • Разные дистрибутивы Linux используют различные реализации cron с разной поддержкой функций.

Синтаксис Crontab: формат из пяти полей

Каждая cron-задача следует этой структуре:

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

Специальные символы:

  • * — любое значение
  • , — разделитель списка (1,3,5)
  • - — диапазон (1-5)
  • / — шаговые значения (*/15 означает каждые 15)

Важно: Символы вроде L, W, # и ? относятся к синтаксису планировщика Quartz, а не к стандартному cron. Не используйте их в Linux crontab. В случае сомнений проверьте документацию вашей системы через man 5 crontab.

Распространённые шаблоны планирования

*/5 * * * *     # Каждые 5 минут
0 * * * *       # В начале каждого часа
0 3 * * *       # Ежедневно в 3 часа утра
0 0 * * 0       # Еженедельно в воскресенье в полночь
0 0 1 * *       # Первый день каждого месяца

Специальные строки

Большинство реализаций cron поддерживают эти сокращения (поддержка может различаться в минималистичных системах вроде BusyBox):

СтрокаЭквивалент
@rebootЗапуск один раз при старте
@hourly0 * * * *
@daily0 0 * * *
@weekly0 0 * * 0
@monthly0 0 1 * *
@yearly0 0 1 1 *

Обратите внимание, что @reboot не гарантирует доступность сети или других сервисов; для задач при запуске с учётом зависимостей systemd timers обычно подходят лучше.

Ловушка: день месяца против дня недели

Когда вы указываете И день месяца, И день недели, cron обрабатывает их как ИЛИ, а не И:

0 0 15 * 1    # Запускается 15-го числа ИЛИ в любой понедельник

Это застаёт многих врасплох. Если вам нужно “15-е число, но только если это понедельник”, обрабатывайте эту логику внутри вашего скрипта.

Работа с окружением

Cron работает с ограниченным, неинтерактивным окружением. Именно здесь большинство задач молча терпят неудачу.

Поведение PATH различается в зависимости от дистрибутива и версии:

  • Некоторые системы определяют минимальный PATH по умолчанию
  • Другие (особенно новые релизы Ubuntu) могут наследовать PATH из окружения сервиса

Не полагайтесь на значения по умолчанию. Для переносимого и предсказуемого поведения явно устанавливайте то, что вам нужно.

Безопасные практики:

# Устанавливайте переменные в начале вашего crontab
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=""

# Всегда используйте абсолютные пути
0 3 * * * /usr/bin/node /home/deploy/app/cleanup.js

Примечание: MAILTO работает только если установлен и настроен локальный MTA. На многих современных серверах его нет. Вместо этого явно перенаправляйте вывод, а не полагайтесь на email.

Вывод и логирование

# Логировать всё
0 3 * * * /path/to/script.sh >> /var/log/myjob.log 2>&1

# Отбросить весь вывод
0 3 * * * /path/to/script.sh >/dev/null 2>&1

# Логировать только ошибки
0 3 * * * /path/to/script.sh >/dev/null 2>> /var/log/myjob-errors.log

Основные команды Crontab

crontab -e    # Редактировать ваш crontab
crontab -l    # Показать текущие задачи
crontab -r    # Удалить все задачи (осторожно!)

Для общесистемных задач используйте файлы в /etc/cron.d/. Обратите внимание, что /etc/cron.daily/, /etc/cron.hourly/ и т.д. выполняются через run-parts, а не сканируются автоматически cron. См. man 8 run-parts для правил именования и выполнения.

Реализации Cron различаются

Разные системы используют разные демоны cron:

  • Debian/Ubuntu: cron (линия Vixie, с патчами дистрибутива)
  • RHEL/Fedora: Cronie
  • Alpine/контейнеры: BusyBox crond

Поддержка функций (специальные строки, поведение почты, логирование) может отличаться. Всегда проверяйте по локальной man-странице crontab(5).

Cron против Systemd Timers

АспектCronSystemd Timers
Сложность настройкиПростаяБолее многословная
Обработка пропущенных задачПропускаютсяНастраиваемая (Persistent=true)
ЗависимостиНетМожет ждать сервисы/монтирование
ЛогированиеРучноеВстроенное journald

Используйте cron когда: Вам нужно простое, переносимое планирование, работающее везде.

Используйте systemd timers когда: Вам нужно управление зависимостями, постоянное планирование между перезагрузками или лучшая интеграция с современными Linux-системами. Документация проекта systemd по timer units является каноническим справочником.

Быстрый чеклист для отладки

  1. Работает ли cron? systemctl status cron или systemctl status crond (имя сервиса зависит от дистрибутива)
  2. Проверьте логи: grep CRON /var/log/syslog (Debian/Ubuntu) или /var/log/cron (RHEL/Fedora)
  3. Протестируйте вашу команду вручную с ограниченным окружением
  4. Проверьте абсолютные пути для всех команд и файлов
  5. Проверьте права доступа к вашему скрипту

Заключение

Cron остаётся самым простым способом планирования задач в Linux. Освойте синтаксис из пяти полей, поймите поведение ИЛИ при комбинировании полей дня, и учитывайте специфичное для дистрибутива поведение окружения. С этими основами ваши запланированные задачи будут надёжно работать годами.

Часто задаваемые вопросы

Наиболее распространённая причина — проблемы с окружением. Cron работает с ограниченным, неинтерактивным окружением, которое отличается от вашей оболочки, и поведение PATH различается в зависимости от дистрибутива. Всегда используйте абсолютные пути, явно устанавливайте необходимые переменные, проверяйте, что сервис cron запущен, и проверяйте системные логи на наличие ошибок.

Используйте поле дня недели с диапазоном от понедельника (1) до пятницы (5). Например, для запуска в 9 утра каждый будний день используйте: 0 9 * * 1-5 /path/to/script.sh. Помните, что в стандартном синтаксисе cron воскресенье — это 0, а суббота — 6.

Пользовательские crontab редактируются через crontab -e и хранятся для каждого пользователя. Системные crontab в /etc/cron.d/ включают дополнительное поле имени пользователя после спецификации времени, чтобы указать, какой пользователь выполняет команду. Системные crontab лучше подходят для сервисов и общего администрирования.

Запустите вашу команду вручную в минимальном окружении, имитирующем cron. Например: env -i PATH=/usr/bin:/bin /path/to/script.sh. Это помогает выявить отсутствующие зависимости или проблемы с путями, которые в противном случае вызвали бы молчаливые сбои.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay