Що таке cron-вираз?
Cron-вираз — це компактний рядок планування, що точно вказує планувальнику завдань, коли виконати задачу. Формат зародився у 1975 році в Unix V7 демоні cron і з тих пір майже не змінився — та сама п'ятипольова граматика сьогодні зустрічається в Kubernetes CronJob, AWS EventBridge, GitHub Actions, Google Cloud Scheduler, GitLab CI, пайплайнах Jenkins та бінарному файлі crontab, що постачається з кожним дистрибутивом Linux. Граматика вміщує багато значення в приблизно тринадцять символів, тому парсер, який перетворює її на просту мову, є різницею між впевненим деплоєм та відкатом о 3 ранку.
Як працює cron-вираз?
Стандартний cron-вираз має п'ять розділених пробілами полів, які разом визначають повторюваний розклад. Рушій перевіряє поточний системний час з виразом кожну хвилину та запускає завдання, коли всі п'ять полів збігаються. Поля зліва направо:
- Хвилина (0–59). На якій хвилині години виконується завдання.
0означає на початку години,30— о половині,*/5— кожні п'ять хвилин (00, 05, 10, ...), а15,45— о чверть та без чверті. - Година (0–23). Яка година дня за 24-годинним форматом.
0— опівночі,9— 9:00,17— 17:00. Діапазони (9-17для робочих годин) та кроки (*/2для кожної другої години) працюють так само, як для хвилин. - День місяця (1–31). Який календарний день виконувати.
1— 1-е числа місяця,*— кожен день,1,15— 1-е та 15-е. Будьте обережні з31— тихо пропускає місяці, що не мають 31-го дня. - Місяць (1–12 або JAN–DEC). Які місяці виконувати.
*— кожен місяць,1,7— січень та липень,1-3— лише перший квартал. Тризначні назви місяців є нечутливими до регістру в більшості реалізацій. - День тижня (0–7, де 0 і 7 означають неділю). Обмежує запуск конкретними днями тижня.
1-5— з понеділка по п'ятницю,0,6— вихідні,MON-FRIпрацює в більшості парсерів. Коли день місяця і день тижня встановлені на конкретні значення, класичний cron запускається при будь-якому збігу (логічне АБО), що кожного разу здивує новачків.
Навіщо використовувати парсер cron-виразів?
- Виявляйте тиху помилку читання до деплою. Вираз `0 2 */3 * *` запускається о 2:00 кожні три дні, а не кожні три хвилини — вставте тут і побачите це простою мовою до відправки у продакшн.
- Більшість хмарних планувальників за замовчуванням працюють в UTC. Перегляд наступних десяти часів запуску у вашому локальному часовому поясі виявляє зсув на годину через перехід на літній час до того, як хтось отримає дзвінок о 3 ранку.
- Ярлики на кшталт `@daily`, `@weekly` та `@monthly` зручні, але неоднозначні. Парсер показує базову п'ятипольову форму, щоб ви точно знали, що було заплановано.
- Будівник поле за полем дозволяє складати розклад по одній колонці і спостерігати, як опис оновлюється наживо, що значно швидше, ніж в десятий раз перечитувати сторінку посібника cron.
Де використовуються cron-вирази?
Синтаксис cron зустрічається скрізь, де завдання потрібно повторювати за годинником. Три найпоширеніші платформи з їхніми специфічними особливостями:
- Розклади резервного копіювання. Класичний запис `crontab -e`, що скидає базу даних на S3 о 2:00 щоночі або ротує архів `pg_dump` 1-го числа кожного місяця. Рядок на кшталт `0 2 * * * /usr/local/bin/backup.sh` встановлений на більшій кількості Linux-серверів, ніж будь-який інший рядок cron в історії.
- Тригери `schedule` у GitHub Actions. Ключ `on.schedule.cron` у `.github/workflows/*.yml` приймає стандартний п'ятипольовий cron, але завдання завжди виконується в UTC, а GitHub мовчки пропустить час запуску, якщо черга runner'а зайнята. Поширений шаблон: `cron: '0 9 * * 1-5'` для відправки дайджесту з понеділка по п'ятницю о 9:00 UTC.
- AWS EventBridge Scheduler. Cron-вирази EventBridge мають шосте поле для року та вимагають `?` замість `*` в одному з полів день-місяця або день-тижня — `cron(0 9 ? * MON-FRI *)` є перекладом EventBridge класичного стандартного cron о 9:00 у будні. Невідповідність зі стандартним синтаксисом cron є першопричиною помилок `ValidationException` у деплоях CloudFormation.
Як виглядає реальний cron-вираз?
Візьмемо 0 9 * * 1-5 — запускається о 9:00, кожен будній день. Читаємо поля зліва направо: 0 — нульова хвилина години, 9 — 9:00 за 24-годинним форматом, * у день-місяця означає кожен календарний день, * у місяць означає кожен місяць, а 1-5 у день-тижня обмежує запуск з понеділка по п'ятницю (де 1 = понеділок у стандартній нумерації cron). Вставте це у поле введення — парсер підтвердить О 09:00, з понеділка по п'ятницю з наступними десятьма датами запуску у вибраному часовому поясі. Той самий намір у синтаксисі AWS EventBridge: cron(0 9 ? * MON-FRI *). Той самий намір як вираз Quartz (шестипольовий з ведучими секундами): 0 0 9 ? * MON-FRI. Три різні платформи, три різні форми, один базовий розклад.
Cron-вирази невибачливі рівно в одному: опечатка дає синтаксично правильний розклад, що виконується не в той час, без помилки для перехоплення під час code review. Читання `0 0 1 * *` з розумінням, що це запуск опівночі 1-го числа кожного місяця, а не 1 січня, вимагає практики. Парсер вище перетворює цю практику на десятисекундну перевірку — вставте вираз, прочитайте опис, перегляньте наступні десять часів запуску у вашому часовому поясі та відправте YAML, знаючи, що cron-рядок дійсно робить те, що написано у повідомленні коміту.
У чому різниця між 5-польовим та 6-польовим cron?
П'ятипольовий cron — це класична Unix-граматика з роздільною здатністю одна хвилина. Шестипольовий cron додає ведучу колонку секунд для підхвилинного планування — використовується Quartz та Spring @Scheduled. AWS EventBridge також використовує шість полів, але його додаткова колонка — завершальний рік, а не секунди.
Що означають @hourly, @daily та @weekly?
Псевдоніми Vixie-cron, введені у 1987 році. @hourly = 0 * * * *, @daily = 0 0 * * *, @weekly = 0 0 * * 0, @monthly = 0 0 1 * *, @yearly = 0 0 1 1 *. @reboot запускається один раз при завантаженні. GitHub Actions та EventBridge не підтримують ці псевдоніми.
Неділя — це день 0 чи день 7 у cron?
Обидва, у класичному Vixie cron — 0 та 7 приймаються, щоб діапазони на кшталт 5-7 читалися природно як п'ятниця-неділя. Понеділок завжди 1, субота завжди 6. Quartz та AWS EventBridge використовують іншу конвенцію: 1-7, де неділя — 1. Перевіряйте документацію платформи перед припущенням.
Як cron обробляє перехід на літній час?
Залежить від часового поясу рушія. В UTC (за замовчуванням для EventBridge, Kubernetes та GitHub Actions) літнього часу не існує. У локальному поясі з переходом на літній час класичний Vixie cron пропускає завдання під час переходу вперед і виконує їх двічі під час переходу назад; systemd-таймери запускаються рівно один раз.