Как пять полей cron пережили поколения Unix

Cron часто представляют как одну старую Unix-программу, которая без изменений дожила до наших дней. Точнее будет сказать, что пережил десятилетия прежде всего её язык: пять календарных полей до сих пор узнаются в Linux, панелях хостинга, Kubernetes и системах непрерывной интеграции, хотя задачи там запускают разные программы с разными правилами.
cron появился раньше Unix Version 7
Обычно историю cron начинают с Unix Version 7 и 1979 года, однако сохранившийся исходный код Unix Sixth Edition датирован маем 1975 года. Программа читала /usr/lib/crontab, разбирала пять полей времени, а затем передавала оставшуюся часть строки командной оболочке. Уже тогда поддерживались звёздочка, списки и диапазоны, а расписание проверялось раз в минуту.
В руководстве Unix Version 7 этот интерфейс был подробно описан: минута, час, день месяца, месяц, день недели и строка для shell. Порядок полей сохранился, но отдельные диапазоны и расширения со временем менялись. Например, в руководстве V7 дни недели нумеровались от 1 до 7, начиная с понедельника, тогда как многие современные реализации считают воскресенье нулём и иногда также принимают значение 7.
Исторические исходники не дают достаточных оснований уверенно назвать автора самой первой версии. В такой ситуации полезнее опираться на то, что можно проверить: к 1975 году cron уже существовал, а к 1979 году его узнаваемый интерфейс был частью документации Unix.
Vixie cron закрепил открытую линию развития
В январе 1987 года Пол Викси начал собственную реализацию cron. В репозитории проекта прямо сказано, что она функционально основана на System V, поэтому называть её полной переработкой с чистого листа было бы неверно. Пользовательские таблицы расписаний к тому моменту также не были новой идеей.
Значение Vixie cron состояло в другом. Это была свободно распространяемая и переносимая реализация совместимого интерфейса, которая объединила пользовательские crontab в защищённом каталоге, команды управления ими, списки разрешений и запретов, переменные окружения, журналирование и отправку вывода по почте. Формат оставался близок к V7, но получил совместимые расширения, в том числе шаги и текстовые названия месяцев и дней недели. Позднее этот код стал предком нескольких вариантов cron в BSD и Linux, хотя конкретный набор возможностей сегодня по-прежнему зависит от установленной реализации.
Пять полей описывают совпадение с календарём
Выражение 30 4 * * 1-5 означает запуск в 04:30 с понедельника по пятницу. Первое поле отвечает за минуту, второе за час, затем идут день месяца, месяц и день недели. Звёздочка разрешает любое значение поля, запятая объединяет несколько значений, дефис задаёт диапазон, а косая черта выбирает каждый n-й элемент внутри указанного поля или диапазона.
Шаг всегда действует только внутри своего поля. Запись */15 в позиции минут означает минуты 0, 15, 30 и 45 каждого подходящего часа, а не интервал в пятнадцать минут с момента предыдущего запуска. Это различие становится заметным после остановки планировщика: обычный cron не хранит очередь таких интервалов, а просто проверяет, совпадает ли текущая календарная минута с выражением.
Есть и менее очевидное правило. В формате Vixie cron, если одновременно ограничены день месяца и день недели, задача запускается при совпадении любого из них. Поэтому 0 9 1 * 1 означает не только понедельник, который выпал на первое число, а каждый понедельник и каждое первое число месяца в 09:00. Другие семейства планировщиков могут трактовать похожую запись иначе.
Само выражение описывает только календарное условие. Оно не содержит команду, рабочий каталог, окружение, правила повторной попытки, ограничение параллельных запусков или место хранения журналов. Эти условия задаёт конкретный планировщик и его конфигурация.

Расписание не определяет условия запуска
Задача cron выполняется не в той же среде, что команда из интерактивного терминала. Набор переменных обычно короче, PATH может отличаться, а профиль пользовательской оболочки чаще всего не загружается. По этой причине скрипт, который успешно запускается вручную, способен завершиться ошибкой по расписанию. Надёжная задача использует предсказуемое окружение, абсолютные пути там, где они действительно нужны, и сохраняет диагностический вывод.
Календарное время тоже требует отдельного решения. Часовой пояс может задаваться системой, демоном или самой таблицей, а переход на летнее время создаёт пропущенные и повторяющиеся локальные минуты. Даже документация современных реализаций различается в деталях обработки перевода часов, поэтому универсального ответа для слова «cron» нет. Нужно проверить локальную страницу руководства и отдельно решить, допустим ли повторный запуск задачи.
Классический cron также не восполняет задания, пропущенные во время выключения компьютера. Для периодических задач на машине, которая работает не постоянно, часто используют anacron или другой планировщик с сохранением состояния. Если выполнение может длиться дольше интервала, защита от одновременных экземпляров и идемпотентность остаются ответственностью самой задачи или внешнего механизма блокировки.
Kubernetes, CI и systemd унаследовали разные части идеи
CronJob в Kubernetes использует знакомую запись расписания, но запускает не shell-команду, а создаёт объекты Job. Контроллер работает приблизительно по расписанию и при определённых обстоятельствах способен создать два задания или не создать ни одного, поэтому документация рекомендует делать операции идемпотентными. Там же отдельно настраиваются политика параллельности, крайний срок запоздалого старта и часовой пояс.
GitHub Actions тоже заимствует POSIX-подобный синтаксис, но ограничивает минимальную частоту, выполняет workflow только из основной ветки и предупреждает о задержках либо потере поставленного в очередь запуска при высокой нагрузке. Пять полей здесь описывают намерение, а фактические гарантии предоставляет уже облачный сервис.
Systemd timers устроены иначе и не являются новым синтаксисом cron. Таймер systemd активирует связанный service unit, умеет задавать как календарные, так и монотонные интервалы, а с Persistent=true может восполнить один пропущенный календарный запуск. Если связанный сервис уже активен, очередное срабатывание таймера не перезапустит его автоматически. Поэтому механическое преобразование cron-выражения в OnCalendar= ещё не делает две конфигурации эквивалентными.
Что делает Cron Parser
Cron Parser разбирает пятичастное выражение прямо в браузере. Можно заполнить поля отдельно или вставить всю строку в одно из них; инструмент понимает числа, звёздочки, списки, диапазоны, шаги, английские названия месяцев и дней недели. Значение 7 для воскресенья приводится к 0, а вопросительный знак в полях дня месяца и дня недели трактуется как звёздочка. Последнее является расширением и переносится не во все планировщики.
После разбора инструмент объясняет каждое поле, показывает часы и минуты запуска для подходящего календарного дня и рассчитывает до десяти ближайших срабатываний в локальном времени браузера или UTC. Поиск ограничен конечным диапазоном, поэтому для редких годовых расписаний список иногда содержит меньше десяти дат. Кнопки с распространёнными макросами подставляют их пятичастные эквиваленты, но вводить @daily или @weekly как самостоятельное выражение нельзя.
Генератор systemd timer предназначен только как начальный шаблон для простых расписаний. Он создаёт секции таймера, но не service unit и не команду, а сложные ограничения по дням, месяцам, спискам и диапазонам не всегда можно перенести автоматически. Кроме того, добавленный Persistent=true меняет поведение после простоя. Перед использованием такой результат нужно проверить и дополнить вручную.
Cron Parser ничего не устанавливает и не запускает: данные остаются в браузере, а итоговое расписание всё равно следует сверить с документацией целевой системы.
Похожие инструменты
Частые вопросы
Когда появился cron и кто его создал?
Исходный код cron есть уже в Unix Sixth Edition за 1975 год. В доступном исходнике автор не указан, поэтому приписывать первую версию конкретному человеку без дополнительного подтверждения некорректно. В Unix Version 7, выпущенной в 1979 году, интерфейс cron был подробно задокументирован и уже очень похож на современный.
Что изменил Vixie cron?
Vixie cron появился в 1987 году как свободно распространяемая и переносимая реализация, функционально основанная на System V. Он не изобрёл cron заново, но закрепил линию развития с пользовательскими crontab, управлением доступом, переменными окружения и совместимыми расширениями, от которой произошли многие варианты cron в BSD и Linux.
Что означают пять полей cron?
Поля задают минуту, час, день месяца, месяц и день недели. После них в crontab обычно следует команда, а в системных таблицах между расписанием и командой может стоять имя пользователя. В реализациях семейства Vixie ограничения по дню месяца и дню недели объединяются по правилу ИЛИ.
Что происходит с задачами при переходе на летнее время или выключенном сервере?
Это зависит от реализации. Классический cron проверяет календарь раз в минуту и обычно не восполняет запуски, пропущенные во время остановки системы. Поведение при переводе часов также различается, поэтому его нужно сверять с документацией установленного cron. Anacron, systemd timers и контроллер CronJob в Kubernetes решают пропуски по своим правилам.
Проверяет ли Cron Parser совместимость с любым планировщиком?
Нет. Инструмент разбирает распространённый пятичастный синтаксис и показывает предварительное расписание, но у Cronie, Quartz, Kubernetes, GitHub Actions и других систем есть собственные расширения и ограничения. Результат нужно сверять с документацией целевой платформы, особенно если используются вопросительный знак, макросы, часовые пояса или преобразование в systemd timer.
Автор
Alex RelFullstack Engineer
В коммерческой разработке с 2011 года — больше 15 лет. Автор двух SaaS-продуктов: TeleGo.io и LingvoHabit.com. Статьи здесь выросли из реальной клиентской и продуктовой работы.



