Що таке cron-вираз? Синтаксис, поля та 15 прикладів
Cron-вираз — це короткий рядок, який підказує планувальнику, коли запускати завдання. Стандартна форма має п’ять полів, розділених пробілами: хвилина, година, день місяця, місяць і день тижня. Наприклад, */15 * * * * означає «кожні 15 хвилин»: */15 у полі хвилин збігається з хвилинами 0, 15, 30 і 45, а чотири зірочки означають будь-яку годину, будь-який день, будь-який місяць і будь-який день тижня.
Спробуйте безкоштовно: Генератор Crontab Безкоштовно, без реєстрації.
Назва походить від cron — планувальника завдань в Unix, але сьогодні той самий синтаксис керує CI-конвеєрами, хмарними планувальниками та фреймворками застосунків, іноді з додатковими полями. У цьому посібнику пояснено синтаксис, 15 перевірених прикладів, поширені варіанти й помилки, через які завдання запускається не в той час. Щоб перевірити будь-який вираз під час читання, вставте його в безкоштовний генератор Crontab, який описує розклад простими словами.
П’ять полів cron-виразу
Поля читаються зліва направо:
| Позиція | Поле | Допустимі значення | Назви |
|---|---|---|---|
| 1 | Хвилина | 0–59 | – |
| 2 | Година | 0–23 | – |
| 3 | День місяця | 1–31 | – |
| 4 | Місяць | 1–12 | jan–dec |
| 5 | День тижня | 0–7 (і 0, і 7 — неділя) | sun–sat |
Години записують у 24-годинному форматі, тож 14:00 — це 14. Назви — це перші три літери англійської назви місяця чи дня, регістр не має значення. Деякі реалізації, зокрема cron у macOS, не приймають назви всередині діапазонів або списків, тому 1-5 переносніший, ніж mon-fri.
У файлі crontab команда йде після п’яти полів: 0 2 * * * /home/me/backup.sh. Загальносистемний /etc/crontab у Linux має ще й поле з іменем користувача перед командою.
Спеціальні символи: зірочка, кома, дефіс і скісна риска
Майже всю роботу виконують чотири символи:
| Символ | Значення | Приклад | Збігається з |
|---|---|---|---|
* |
Будь-яке значення | * у полі годин |
Години 0, 1, 2 … 23 |
, |
Список | 8,20 у полі годин |
Години 8 і 20 |
- |
Діапазон (включно) | 1-5 у полі дня тижня |
З понеділка по п’ятницю |
/ |
Крок | */15 у полі хвилин |
Хвилини 0, 15, 30, 45 |
Їх можна поєднувати. 9-17/2 у полі годин збігається з 9, 11, 13, 15 і 17, а 0-4,8-12 — це список із двох діапазонів.
Крок починається заново в кожному циклі. */7 у полі хвилин збігається з 0, 7, 14 … 56, а на початку наступної години знову з 0, тож між :56 і :00 минає чотири хвилини, а не сім. Крок, на який 60 хвилин або 24 години не діляться без остачі, ніколи не дає цілком рівномірного інтервалу.
15 прикладів cron-виразів
Кожен приклад перевірено поле за полем. Час указано в часовому поясі планувальника.
| Cron-вираз | Коли запускається |
|---|---|
* * * * * |
Щохвилини |
*/5 * * * * |
Кожні 5 хвилин (:00, :05, :10 …) |
30 * * * * |
Щогодини о 30-й хвилині (00:30, 01:30 …) |
0 */2 * * * |
Кожні 2 години рівно (00:00, 02:00 … 22:00) |
0 2 * * * |
Щодня о 02:00 |
0 8,20 * * * |
Двічі на день, о 08:00 і 20:00 |
0 9 * * 1-5 |
З понеділка по п’ятницю о 09:00 |
*/15 9-17 * * 1-5 |
Кожні 15 хвилин з 09:00 до 17:45, з понеділка по п’ятницю |
0 6 * * 0,6 |
У суботу й неділю о 06:00 |
0 0 * * 0 |
Щонеділі опівночі |
0 22 * * 5 |
Щоп’ятниці о 22:00 |
0 0 1 * * |
1-го числа кожного місяця опівночі |
0 12 15 * * |
15-го числа кожного місяця о 12:00 |
0 0 1 1,4,7,10 * |
Щокварталу: 1 січня, квітня, липня й жовтня опівночі |
0 0 1 1 * |
Раз на рік, 1 січня опівночі |
Дві деталі легко пропустити. По-перше, діапазони включають обидва кінці, тож 9-17 містить годину 17: */15 9-17 * * 1-5 запускається 36 разів на день, а останній запуск — о 17:45, а не о 17:00. По-друге, 0 0 1 */3 * дає такий самий щоквартальний розклад, бо */3 у полі місяця починається з 1 і збігається з місяцями 1, 4, 7 і 10.
Нестандартні макроси: @daily, @weekly і @reboot
Багато реалізацій cron приймають ключове слово замість п’яти полів:
| Макрос | Відповідає | Запускається |
|---|---|---|
@yearly або @annually |
0 0 1 1 * |
Опівночі 1 січня |
@monthly |
0 0 1 * * |
Опівночі 1-го числа кожного місяця |
@weekly |
0 0 * * 0 |
У неділю опівночі |
@daily або @midnight |
0 0 * * * |
Щодня опівночі |
@hourly |
0 * * * * |
На 0-й хвилині кожної години |
@reboot |
– | Один раз, коли запускається демон cron |
Vixie cron, cronie та cron у macOS підтримують усі ці макроси, а CronJob у Kubernetes приймають ті, що прив’язані до часу, але не @reboot. Вони не входять до стандарту POSIX, тож перш ніж використовувати їх деінде, перевірте документацію.
Варіанти cron: секунди, роки й додаткові символи
Не кожен планувальник читає п’ять полів, тож перевірте, для якого діалекту ви пишете.
- Quartz (Java) використовує шість або сім полів: секунди, хвилини, години, день місяця, місяць, день тижня й необов’язковий рік. Одне з двох полів дня має бути
?(«без конкретного значення»). Quartz також підтримуєL(останній),W(найближчий робочий день) і#(n-й день тижня в місяці):0 15 10 L * ?запускається о 10:15 в останній день кожного місяця, а0 15 10 ? * 6#3— о 10:15 у третю п’ятницю, бо Quartz нумерує дні тижня від 1 до 7, починаючи з неділі. - Вирази Spring в
@Scheduled(cron = "…")мають шість полів: спочатку секунди, потім звичні п’ять, без року. - Правила AWS EventBridge використовують
cron(minutes hours day-of-month month day-of-week year): шість полів, без секунд, рік у кінці та?в одному з двох полів дня.cron(0 12 * * ? *)запускається щодня о 12:00 UTC. Правила на шині подій працюють в UTC, а EventBridge Scheduler дає змогу вибрати часовий пояс. Як і Quartz, AWS нумерує дні тижня від 1 до 7, де 1 — неділя. - CronJob у Kubernetes використовують стандартні п’ять полів у
spec.schedule. Безspec.timeZoneрозклад іде за часовим поясом kube-controller-manager. Щоб зафіксувати пояс, укажіть назву IANA, наприкладEurope/Berlin. - Тригери
scheduleу GitHub Actions використовують п’ять полів і працюють за UTC, якщо Ви не вкажете необов’язковий часовий пояс IANA. Найкоротший підтримуваний інтервал — п’ять хвилин, макроси на кшталт@dailyне підтримуються, а заплановані запуски можуть затримуватися, коли GitHub перевантажений, особливо на початку кожної години.
Пастка з днем місяця й днем тижня
У стандартному cron (Vixie) два поля дня поєднуються через АБО, а не через І, якщо обидва обмежені. Якщо одне з них — *, враховується лише інше. Тож 0 9 1-7 * 1 не означає «перший понеділок місяця». Завдання запускається о 09:00 у кожен із днів від 1 до 7 і додатково щопонеділка — разом 10 або 11 запусків на місяць.
Щоб запускати його лише в перший понеділок, залиште у виразі одне поле дня, а інше перевіряйте в команді:
0 9 1-7 * * [ "$(date +\%u)" = 1 ] && /path/to/report.sh
date +%u виводить день тижня числом від 1 до 7, де понеділок = 1. Знак відсотка треба екранувати як \%, бо cron перетворює неекранований % у команді на перенесення рядка. Quartz і AWS уникають цієї неоднозначності, вимагаючи ? в одному з двох полів дня.
Часові пояси й літній час
Cron працює в часовому поясі машини чи сервісу, що обчислює вираз, а на серверах і хмарних платформах це часто UTC, а не ваш місцевий час. 0 9 * * * на сервері з UTC запускається о 09:00 UTC, тобто о 05:00 у Нью-Йорку в період літнього часу (UTC−4). Конвертер часових поясів допоможе перевести місцевий час у пояс планувальника.
Літній час додає два особливі випадки в поясах, де його переводять: коли годинники переводять уперед, однієї місцевої години не існує, а коли назад — одна година трапляється двічі. Cron у Debian і cronie компенсують невеликі зміни годинника для завдань із фіксованим часом: запуск, що припадає на пропущену годину, відбувається невдовзі після переведення, а запуск у повторюваній годині не повторюється. Інші планувальники поводяться інакше, тож найнадійніше — тримати сервери в UTC або не ставити важливі завдання на години переведення годинників, зазвичай між 01:00 і 03:00 за місцевим часом.
Як перевірити cron-вираз
Помилковий cron-вираз рідко спричиняє повідомлення про помилку: завдання просто запускається не в той час або не запускається взагалі. Коротка процедура виявляє більшість проблем:
- Прочитайте вираз словами. Вставте його в інструмент, який описує розклад, і перевірте, чи речення відповідає задуму, особливо щодо двох полів дня.
- Перевірте команду з коротким розкладом. Тимчасово поставте
* * * * *, щоб завдання запустилося протягом хвилини, а потім поверніть справжній розклад. - Зберігайте вивід. Додайте
>> /tmp/myjob.log 2>&1після команди, щоб помилки записувалися у файл, а не губилися. - Перегляньте журнал cron. Використовуйте
grep CRON /var/log/syslogабоjournalctl -u cronу Debian та Ubuntu іjournalctl -u crondу Fedora та RHEL. - Використовуйте абсолютні шляхи. Cron запускає завдання з мінімальним оточенням і коротким
PATH, тож команда, яка працює у вашому терміналі, може не спрацювати в cron.
Створіть вираз за допомогою генератора Crontab
Безкоштовний генератор Crontab працює повністю у вашому браузері. Введіть вираз або натисніть швидкий шаблон, як-от «Кожні 15 хв», «Щодня о 2:00» чи «Щопонеділка», і інструмент:
- перевіряє синтаксис і повідомляє, якщо вираз недійсний;
- описує розклад простими словами (англійською);
- приймає п’ять стандартних полів, необов’язкове поле секунд на початку, назви місяців і днів тижня, а також 7 для неділі;
- розгортає макроси на кшталт
@weeklyу відповідний вираз із п’яти полів і пояснює, що робить@reboot; - показує шпаргалку з кожним символом і прикладом.
Перемикачі дають змогу отримати докладніший опис, 24-годинний формат і вибрати, чи номери днів тижня починаються з 0 для неділі. Символи, притаманні лише Quartz (L, W, #), і поле року не приймаються. Інструмент лише створює й перевіряє вираз; щоб запланувати завдання, скопіюйте його в crontab -e або в конфігурацію вашої платформи.
Поширені запитання
Чим cron відрізняється від crontab?
Cron — це фонова служба (демон), яка виконує заплановані завдання. Crontab, скорочення від «cron table», — це файл, у якому їх перелічено, по одному завданню в рядку: cron-вираз, а за ним команда. Власний crontab можна редагувати командою crontab -e, а переглянути — crontab -l.
Чи може cron-завдання запускатися кожні 30 секунд?
У стандартному cron — ні, бо його найменша одиниця — хвилина. Планувальники з полем секунд це вміють: Spring приймає */30 * * * * *, а Quartz потребує ? в одному з полів дня, як у */30 * * * * ?. У класичному cron поширений обхідний шлях — два рядки, що запускаються щохвилини, причому в одному з них перед командою стоїть sleep 30;.
Як запускати cron-завдання в останній день місяця?
У стандартному cron немає символу «останній день», але Quartz і AWS підтримують L у полі дня місяця. У класичному cron заплануйте дні з 28 по 31 і дайте команді перевірити, чи завтра 1-ше число:
0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = "01" ] && /path/to/job.sh
date -d tomorrow — це синтаксис GNU date, який використовують у Linux. У macOS замість нього застосовуйте date -v+1d.
Спробуйте безкоштовно: Генератор Crontab Безкоштовно, без реєстрації.