Шпаргалка Crontab: 50+ выражений cron, синтаксис и гид по современным планировщикам
Cron-выражение — это пять полей (минута, час, день месяца, месяц, день недели) и команда после них. Та же грамматика планирует задачи в Unix с 1979 года, а сегодня её используют Kubernetes CronJob, GitHub Actions, AWS EventBridge и cron-триггеры Vercel. Выучите синтаксис один раз, и он пригодится почти везде.
Страница для разработчиков, которым выражение нужно прямо сейчас: задача в Linux, Kubernetes CronJob, триггер GitHub Actions или разбор полётов, почему пятиминутная задача запускается раз в час. Перейдите к таблице быстрого справочника за готовыми выражениями, к разделу «Разбор синтаксиса» за правилами полей или откройте Генератор crontab — конструктор и парсер cron-выражений — privacy-first альтернатива crontab guru, которая работает в браузере — для проверки выражений в реальном времени.
Таблица быстрого справочника cron-выражений
Тридцать выражений покрывают около 90% реальных задач планирования. Каждое из них — корректный POSIX cron из пяти полей: вставляйте в crontab -e, в schedule: для Kubernetes или в cron: для GitHub Actions.
| Расписание | Cron-выражение | Простыми словами |
|---|---|---|
| Каждую минуту | * * * * * | каждую минуту, весь день, каждый день |
| Каждые 5 минут | */5 * * * * | минуты 0, 5, 10, …, 55 |
| Каждые 15 минут | */15 * * * * | минуты 0, 15, 30, 45 |
| Каждые 30 минут | */30 * * * * | минуты 0 и 30 |
| Каждый час | 0 * * * * | в начале каждого часа |
| Каждые 2 часа | 0 */2 * * * | часы 0, 2, 4, …, 22 |
| Каждые 6 часов | 0 */6 * * * | часы 0, 6, 12, 18 |
| Дважды в день (9:00 и 21:00) | 0 9,21 * * * | в минуту 0 часов 9 и 21 |
| По будням в 9:00 | 0 9 * * 1-5 | Пн-Пт 09:00 |
| По выходным в 9:00 | 0 9 * * 0,6 | Сб и Вс 09:00 |
| Ежедневно в полночь | 0 0 * * * | каждый день в 00:00 |
| Ежедневно в 02:30 | 30 2 * * * | пакетные задачи в часы низкого трафика |
| Каждый понедельник в 9:00 | 0 9 * * 1 | по понедельникам 09:00 |
| Каждую пятницу в 17:00 | 0 17 * * 5 | по пятницам 17:00 |
| Каждое воскресенье в полночь | 0 0 * * 0 | эквивалент @weekly |
| Первого числа в полночь | 0 0 1 * * | 1-е число 00:00, эквивалент @monthly |
| 15-го числа каждого месяца в полдень | 0 12 15 * * | окно для расчёта зарплаты в середине месяца |
| Проверка последнего дня (обёртка) | 0 0 28-31 * * + скрипт | требует проверку даты |
| Ежеквартально (1 янв/апр/июл/окт) | 0 0 1 JAN,APR,JUL,OCT * | первый день каждого квартала |
| Раз в год (1 января) | 0 0 1 1 * или @yearly | полночь Нового года |
| Каждые 5 мин по будням 9-17 | */5 9-17 * * 1-5 | опрос в рабочие часы |
| Каждые 30 мин по выходным | */30 * * * 0,6 | мониторинг Сб/Вс |
| Дважды в час, 15 и 45 | 15,45 * * * * | сдвиг от наплыва в :00 |
| Первый понедельник (обёртка) | 0 9 1-7 * 1 + проверка AND | нужна обёртка (см. ниже) |
| Макросы | @hourly @daily @weekly @monthly @yearly | нестандартные, но широко поддерживаются |
| Только при перезагрузке | @reboot | нестандартный, только vixie cron |
Вставьте любое из них в Генератор crontab — конструктор и парсер cron-выражений, чтобы увидеть пять ближайших запусков. Это самая быстрая проверка перед деплоем.
Разбор синтаксиса cron — 5 полей
Cron-выражение состоит из пяти полей, разделённых пробелами, и команды. Каждое поле управляет одним срезом расписания. Это основа синтаксиса cron-выражений во всех планировщиках из этого гида.
┌──────────── minute (0 - 59)
│ ┌────────── hour (0 - 23)
│ │ ┌──────── day-of-month (1 - 31)
│ │ │ ┌────── month (1 - 12 or JAN-DEC)
│ │ │ │ ┌──── day-of-week (0 - 6 or SUN-SAT; 0 and 7 both mean Sunday)
│ │ │ │ │
* * * * * command-to-run
Мнемоника: «Минута, Час, День месяца, Месяц, День недели», слева направо, от меньшей единицы к большей.
Допустимые значения по полям
| Поле | Диапазон | Псевдонимы | Примечания |
|---|---|---|---|
| Минута | 0-59 | нет | 0 значит «в начале часа» |
| Час | 0-23 | нет | 24-часовой формат; 0 — полночь, 12 — полдень |
| День месяца | 1-31 | нет | для несуществующих дней (31 февраля) задача молча не запускается |
| Месяц | 1-12 | JAN, FEB, MAR, …, DEC | регистр не важен |
| День недели | 0-7 | SUN, MON, TUE, …, SAT | и 0, и 7 означают воскресенье |
Операторы подробно
Пять операторов покрывают любое стандартное cron-выражение:
| Оператор | Значение | Пример | Раскрывается в |
|---|---|---|---|
* | любое значение | * * * * * | каждую минуту |
, | список | 0 9,12,17 * * * | 09:00, 12:00, 17:00 |
- | диапазон (включительно) | 0 9-17 * * * | каждый час с 09:00 по 17:00 |
/ | шаг | */15 * * * * | минуты 0, 15, 30, 45 |
| смешанные | комбинация | 0 9-12,14-17 * * * | утро + день, перерыв на обед |
Оператор шага требует отдельного пояснения. */N отсчитывается от минимального значения поля, а не от текущего времени. */15 значит «минуты 0, 15, 30, 45 каждого часа», а не «каждые 15 минут начиная с этого момента». Сохраните в 12:03, следующий запуск будет в 12:15. С ненулевой базой 5/15 читается как «старт в 5, потом каждые 15»: минуты 5, 20, 35, 50.
Именованные месяцы и дни недели
Месяцы и дни недели можно записывать именами, регистр не важен:
0 0 1 JAN,APR,JUL,OCT * # первый день каждого квартала
0 9 * * MON-FRI # по будням в 9 утра
0 17 * * FRI # пятница в 17:00
Имена удобнее читать при код-ревью, числовая запись чуть переносимее. Выберите один стиль на проект.
Нестандартные макросы: @reboot, @daily и компания
Большинство реализаций cron принимают шесть макросов-сокращений:
| Макрос | Раскрывается в | Значение |
|---|---|---|
@yearly / @annually | 0 0 1 1 * | раз в год, 1 января в полночь |
@monthly | 0 0 1 * * | первого числа каждого месяца в полночь |
@weekly | 0 0 * * 0 | каждое воскресенье в полночь |
@daily / @midnight | 0 0 * * * | каждый день в полночь |
@hourly | 0 * * * * | в начале каждого часа |
@reboot | (особый) | один раз при запуске демона cron |
Эти макросы нестандартны: vixie cron и cronie их поддерживают, а Kubernetes CronJob, GitHub Actions и AWS EventBridge — нет. Для переносимости пишите форму из пяти полей. @reboot редко работает в контейнерах, где демон cron обычно не является init-процессом.
50+ готовых cron-выражений (сгруппированы по сценарию)
В таблице быстрого справочника собраны частые случаи. Этот раздел углубляется в шесть категорий с более плотными примерами cron-задач.
Каждые N минут
* * * * * # каждую минуту
*/2 * * * * # каждые 2 минуты
*/5 * * * * # каждые 5 минут — классический сценарий «cron expression every 5 minutes»
*/10 * * * * # каждые 10 минут
*/15 * * * * # каждые 15 минут
*/30 * * * * # каждые 30 минут
0,30 * * * * # явные минуты 0 и 30 (то же, что */30)
*/45 * * * * # ВНИМАНИЕ: срабатывает только в 0 и 45, затем переход через час
*/45 — классическая ловушка: минута бывает 0-59, поэтому срабатывание ложится на 0 и 45, а затем переходит на следующий час. Для настоящей каденции в 45 минут нужен внешний воркер.
Варианты по часам
0 * * * * # каждый час в :00
30 * * * * # каждый час в :30
0 */2 * * * # каждые 2 часа, в чётный час
0 */6 * * * # каждые 6 часов
0 */12 * * * # дважды в день в 00:00 и 12:00
15 */2 * * * # каждые 2 часа, смещение на 15 мин (без всплеска в :00)
Ежедневно в заданное время
0 0 * * * # полночь (= @daily / @midnight)
30 2 * * * # 02:30 — пакетное окно низкого трафика
0 9 * * * # 09:00
45 23 * * * # 23:45 — итоговые сводки конца дня
0 9,12,17 * * * # три раза в день
0 9-17 * * * # каждый час с 09:00 по 17:00 включительно
Еженедельные расписания
0 9 * * 1-5 # по будням в 9 утра
0 9 * * 0,6 # по выходным в 9 утра
0 18 * * 5 # пятницы в 18:00
0 0 * * 0 # воскресенье в полночь (= @weekly)
0 9 * * MON,WED,FRI # Пн/Ср/Пт в 9 утра
*/30 9-17 * * 1-5 # каждые 30 мин, рабочие часы, по будням
Ежемесячно и ежеквартально
0 0 1 * * # 1-е число месяца в полночь (= @monthly)
0 0 15 * * # 15-е — окно расчёта зарплаты
0 0 1,15 * * # 1-е и 15-е — два раза в месяц
0 0 1 */3 * # ежеквартально: 1 января, апреля, июля, октября
0 0 1 JAN,APR,JUL,OCT * # то же, именованные месяцы
0 0 28-31 * * # последние дни — в паре с обёрткой, проверяющей дату
Последний день месяца не выражается в нативном POSIX. Запустите обёртку, проверяющую date -d tomorrow +%d = 01, или возьмите планировщик с нативной поддержкой (в Quartz есть L; в Kubernetes — нет).
Раз в год и макросы-сокращения
0 0 1 1 * # 1 января в полночь (= @yearly / @annually)
0 0 25 12 * # Рождество в полночь
@yearly # = 0 0 1 1 *
@monthly # = 0 0 1 * *
@weekly # = 0 0 * * 0
@daily # = 0 0 * * *
@hourly # = 0 * * * *
@reboot # особый: один раз при старте демона (только vixie cron)
Любое из этих выражений можно вставить в Генератор crontab — конструктор и парсер cron-выражений для предпросмотра пяти ближайших срабатываний. Это самый дешёвый «дымовой» тест перед деплоем.
Cron против systemd timers против облачных планировщиков — матрица решений
Cron — выбор по умолчанию, но не всегда лучший. Сравнение семи самых распространённых планировщиков пригодится для решений «cron vs systemd timer», «Kubernetes CronJob vs Vercel cron job» или миграции с crontab в управляемое облако.
| Возможность | vixie cron | systemd timer | K8s CronJob | GHA schedule | AWS EventBridge | Vercel Cron | Cloudflare Workers |
|---|---|---|---|---|---|---|---|
| Синтаксис полей | 5 полей POSIX | спецификация OnCalendar | 5 полей POSIX + timeZone | 5 полей POSIX | 6 полей Quartz с ? | 5 полей POSIX | 5 полей POSIX |
| Минимальный интервал | 1 минута | 1 секунда | 1 минута | best-effort, рекомендуется ≥15 мин | 1 минута | 1 минута (план Pro) | 1 минута |
| Явный часовой пояс | CRON_TZ= | Persistent=true | spec.timeZone (1.27+) | только UTC | ScheduleExpressionTimezone | только UTC | только UTC |
| Восстановление пропущенных | нет (нужен anacron) | да (Persistent=true) | да (startingDeadlineSeconds) | нет | да | нет | нет |
| Retry / backoff | нет | частично | да (backoffLimit) | retry при сбое | да | нет | да |
| Контроль конкурентности | нет (нужен flock) | частично | да (concurrencyPolicy) | нет | нет | нет | нет |
Поддержка @reboot | да | да (через OnBootSec=) | нет | нет | нет | нет | нет |
systemd timers — когда выбрать вместо cron
На systemd-Linux таймеры — серьёзная альтернатива: читаемый календарный синтаксис, интеграция с журналом, восстановление пропущенных запусков. Таймер и сопутствующий сервис:
# daily-report.timer
[Unit]
Description=Run daily report at 9 AM
[Timer]
OnCalendar=*-*-* 09:00:00
Persistent=true
Unit=daily-report.service
[Install]
WantedBy=timers.target
# daily-report.service
[Unit]
Description=Daily report job
[Service]
Type=oneshot
ExecStart=/usr/local/bin/daily-report.sh
User=reporter
Включите командой systemctl enable --now daily-report.timer. Главная фишка — Persistent=true: если в 9:00 машина была выключена, таймер сработает сразу после загрузки. У vixie cron такого нет без anacron. Об усилении сервисов читайте в материале security best practices.
Kubernetes CronJob
Kubernetes оборачивает POSIX-расписание примитивами для конкурентности, истории и явного часового пояса:
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-report
spec:
schedule: "0 2 * * *"
timeZone: "America/New_York" # Kubernetes 1.27+
concurrencyPolicy: Forbid # never run two at once
startingDeadlineSeconds: 300 # skip if delayed >5 min
jobTemplate:
spec:
backoffLimit: 2
template:
spec:
restartPolicy: OnFailure
containers:
- name: reporter
image: reporter:1.4.0
command: ["/usr/local/bin/report.sh"]
concurrencyPolicy: Forbid — это аналог flock. Без него долго работающая задача наслаивается на следующий запуск. Полный список настроек — в разделе справочника полей.
Подводные камни GitHub Actions schedule
GitHub Actions принимает стандартный POSIX cron из пяти полей:
on:
schedule:
- cron: '0 9 * * 1-5' # weekdays at 9 AM UTC
Best-effort: при высокой нагрузке на runner-ах GitHub задачи могут запуститься на минуты позже или вовсе пропуститься. Избегайте интервалов короче пятнадцати минут. Настройки часового пояса нет, всегда UTC.
AWS EventBridge — шесть полей в стиле Quartz
AWS EventBridge использует cron в стиле Quartz: шесть полей и обязательный ? в одном из слотов дня:
cron(0 9 * * ? *)
Порядок полей: Minutes Hours Day-of-month Month Day-of-week Year. Когда одно из полей дня ограничено, второе должно быть ? (так Quartz разрешает неоднозначность OR из POSIX). Прямая копия из Linux crontab не пройдёт валидацию.
Vercel Cron, Cloudflare Workers, Render Cron Jobs
Новые serverless-платформы стандартизировались на POSIX из пяти полей. Vercel cron job живёт в vercel.json как { "crons": [{ "path": "/api/cron/nightly", "schedule": "0 2 * * *" }] }. Cron Triggers для Cloudflare Workers задаются в wrangler.toml:
[triggers]
crons = ["*/15 * * * *", "0 9 * * 1-5"]
Render использует render.yaml. Все три работают в UTC без отдельной настройки часового пояса для каждого расписания. Проектируйте в UTC с самого начала.
7 ловушек отладки cron (и как их поймать)
За большинством отчётов «моя cron-задача не запускается» стоит одна из семи причин. Пройдите этот список, прежде чем винить планировщик.
Ловушка 1: минимальный PATH
Cron стартует задачи с минимальным $PATH, обычно /usr/bin:/bin. В вашем интерактивном shell есть /usr/local/bin, ~/.cargo/bin и десяток записей из .bashrc. В cron их нет. Это причина номер один в категории cron debugging path environment.
Симптом: node: command not found. Решение: задайте PATH в начале crontab или используйте абсолютные пути.
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin
*/15 * * * * /usr/local/bin/poll-api.sh
0 9 * * * /home/deploy/.cargo/bin/my-rust-cli
Ловушка 2: stdout и stderr теряются молча
По умолчанию вывод cron уходит в почтовый спул, который никто не читает. Задача молча падает. Перенаправьте оба потока:
*/15 * * * * /usr/local/bin/job.sh >> /var/log/job.log 2>&1
Для вывода в JSON используйте jq, для извлечения строк лога — нашу шпаргалку по regex. У systemd-таймеров вывод собирает journalctl -u your-timer.service.
Ловушка 3: расхождение часовых поясов между dev и prod
Вы написали 0 9 * * * на ноутбуке в Нью-Йорке, ожидая 9 утра по восточному. Сервер живёт в UTC. Cron срабатывает в 9 утра UTC, а это 4 утра по восточному, никто не заметит. Решение: переведите серверы на UTC и пишите расписания в UTC или закрепляйте часовой пояс явно.
CRON_TZ=America/New_York
0 9 * * * /usr/local/bin/morning-report.sh
CRON_TZ работает в vixie cron 3.0+; в Kubernetes 1.27+ есть spec.timeZone; в AWS EventBridge — ScheduleExpressionTimezone; GitHub Actions всегда в UTC. Про UTC, DST и арифметику epoch — наш гид по Unix timestamp.
Ловушка 4: неэкранированный % в командах
Cron трактует неэкранированный % как перевод строки, остаток строки уходит на stdin команде. Поэтому date +"%Y-%m-%d" ломается. Экранируйте каждый % как \% или вынесите логику в скрипт:
0 0 * * * echo "Run at $(date +"\%Y-\%m-\%d")" >> /tmp/log
Ловушка 5: перекрывающиеся запуски
Задача */5 * * * *, иногда выполняющаяся семь минут, запустит следующий экземпляр до завершения предыдущего. Две копии будут драться за одну строку, lock-файл и квоту API. Сериализуйте с flock:
*/5 * * * * flock -n /tmp/job.lock /usr/local/bin/job.sh
-n мгновенно выходит, если блокировка занята. В Kubernetes — concurrencyPolicy: Forbid. Права на lock-файл важны, см. security best practices.
Ловушка 6: @reboot в контейнерах
@reboot срабатывает один раз при запуске демона cron. В виртуальной машине это совпадает с загрузкой. В контейнере демон cron, как правило, не является PID 1 и может вообще не запускаться. В контейнерах @reboot не используйте, логику разового запуска при старте уберите в entrypoint или init-контейнер.
Ловушка 7: семантика OR для day-of-month / day-of-week в POSIX
Это самая дорогая ловушка cron. Правило POSIX: когда ограничены оба поля (ни одно не *), расписание срабатывает, если совпадает любое из них.
0 0 1 * 5 выглядит как «полночь 1-го числа, только по пятницам», но срабатывает 1-го числа И каждую пятницу: шесть-десять лишних запусков в месяц.
# WRONG: looks like "1st of the month, only if Friday"
0 0 1 * 5
# RIGHT: pick one constraint
0 0 1 * * # every 1st of the month
0 0 * * 5 # every Friday
# AND semantics need a wrapper
0 0 1-7 * 5 [ "$(date +\%u)" = "5" ] && /script # first Friday only
Вставьте подозрительные выражения в Генератор crontab — конструктор и парсер cron-выражений. Предпросмотр ближайших запусков делает ловушку OR очевидной.
Современные планировщики — когда НЕ брать cron
Cron уместен для «выполнять эту команду примерно в это время на фиксированной каденции». Он не подходит для нескольких смежных задач:
- Воркфлоу с зависимостями (запустить A, затем B при успехе A) → Airflow, Prefect, Dagster.
- Retry, exponential backoff, dead-letter queues → Temporal, AWS Step Functions, Sidekiq.
- Интервалы меньше минуты → долгоживущий воркер, спящий между итерациями.
- Точность до секунды → отдельный демон; управляемые планировщики не гарантируют точное время.
- Событийная обработка → webhook, очереди сообщений, потоки CDC.
Cron при этом никуда не уходит: Airflow, Step Functions и Sidekiq принимают cron-выражения на входе своих воркфлоу. Грамматика из пяти полей переиспользуется.
Справочник полей Kubernetes CronJob
Матрица решений показала минимальный CronJob. Полный справочник полей для синтаксиса kubernetes cronjob:
| Поле | По умолчанию | Что делает |
|---|---|---|
schedule | обязательное | POSIX-выражение cron из 5 полей |
timeZone | TZ контроллера | явный часовой пояс (1.27+); используйте имена IANA |
concurrencyPolicy | Allow | Forbid пропускает новые запуски, пока активен предыдущий; Replace отменяет предыдущий |
startingDeadlineSeconds | без ограничений | пропустить запуск при задержке больше указанной |
successfulJobsHistoryLimit | 3 | сколько успешных Job сохранить |
failedJobsHistoryLimit | 1 | сколько неуспешных Job сохранить |
suspend | false | поставить на паузу без удаления |
backoffLimit | 6 | количество повторов Pod до пометки Job как Failed |
activeDeadlineSeconds | не задано | жёсткий лимит времени работы Pod |
ttlSecondsAfterFinished | не задано | автоудаление Job через указанное число секунд |
Две частые ошибки: забыли timeZone, и расписание идёт по часовому поясу хоста kube-controller-manager (на управляемом Kubernetes это непредсказуемо); на расписании раз в минуту значение по умолчанию successfulJobsHistoryLimit: 3 накапливает три Job-объекта в минуту, если не задан ttlSecondsAfterFinished.
Кросс-платформенные аналоги cron
macOS launchd. Apple рекомендует launchd вместо cron. Задача launchd — это .plist в ~/Library/LaunchAgents/:
<plist version="1.0"><dict>
<key>Label</key><string>com.example.daily</string>
<key>ProgramArguments</key><array><string>/usr/local/bin/daily.sh</string></array>
<key>StartCalendarInterval</key>
<dict><key>Hour</key><integer>9</integer><key>Minute</key><integer>0</integer></dict>
</dict></plist>
Загрузка командой launchctl load ~/Library/LaunchAgents/com.example.daily.plist. В отличие от cron, launchd подбирает пропущенные запуски после sleep/wake.
Windows Task Scheduler использует schtasks:
schtasks /create /tn "DailyReport" /tr "C:\scripts\report.bat" /sc DAILY /st 09:00
schtasks /create /tn "EveryFifteen" /tr "C:\scripts\poll.bat" /sc MINUTE /mo 15
В WSL нативный Linux cron работает, но останавливается при завершении сессии. Для долгоживущих задач WSL используйте Task Scheduler.
Cron в Docker-контейнерах. В большинстве облегчённых образов (alpine, debian-slim, distroless) демона cron нет. Установите cronie или busybox-cron и запускайте его как PID 1 через tini или s6-overlay. Чаще всего проще взять Kubernetes CronJob.
Продвинутые приёмы и паттерны
Последний день месяца
В cron нет нативного оператора «последний день». Запускайте каждый день в окне 28-31 и проверяйте, что завтра 1-е число:
0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = "01" ] && /usr/local/bin/eom.sh
N-й день недели в месяце
«Первый понедельник» — тот же паттерн с обёрткой: ограничьте дни 1-7, затем проверьте день недели:
0 9 1-7 * * [ "$(date +\%u)" = "1" ] && /usr/local/bin/first-monday.sh
Для «последней пятницы» возьмите дни 25-31 и ту же проверку дня недели.
Случайное смещение для размазывания нагрузки
Когда одну и ту же cron-задачу гоняет много машин, 0 0 * * * создаёт волну запросов в полночь UTC. Подмешайте случайную задержку:
RANDOM_DELAY=10 # cronie / anacron, in minutes
0 0 * * * /usr/local/bin/job.sh
0 0 * * * sleep $((RANDOM \% 600)); /usr/local/bin/job.sh # portable
Мониторинг по «сердцебиению»
Cron падает молча. Паттерн dead-man’s switch: после каждого успешного запуска задача пингует сервис мониторинга, а тот шлёт алерт, если ожидаемый пинг не пришёл. У Healthchecks.io, Cronitor и Dead Man’s Snitch есть бесплатные тарифы.
*/15 * * * * /usr/local/bin/job.sh && curl -fsS --retry 3 https://hc-ping.com/your-uuid
Для логики мониторинга с ветвлением по кодам ответа (200 — здоров, 429 — rate-limit, 503 — деградация) смотрите нашу шпаргалку по HTTP status codes.
Идемпотентность — свойство задачи, а не планировщика
В cron нет ни retry, ни восстановления пропущенных запусков, ни контроля конкурентности. Самое надёжное решение — сделать саму задачу безопасной для многократного запуска. Вместо «отправить сегодняшний отчёт в 9 утра» проектируйте её как «отправить сегодняшний отчёт, если ещё не отправлен». Тогда пропущенные запуски, дубли и ручные подгоны сводятся к одному и тому же состоянию.
FAQ
*/5 * * * * действительно срабатывает каждые 5 минут?
Почти — */5 * * * * привязано к минуте 0, а не к «каждые 5 минут от текущего момента». Срабатывание происходит в минуты 0, 5, 10, …, 55 каждого часа. Шаг */N отсчитывается от минимального значения поля, а не от текущего времени. Сохраните в 12:03, следующий запуск будет в 12:05, а не в 12:08.
Что означает 0 0 * * * в cron?
0 0 * * * означает каждый день в полночь (00:00) по локальному часовому поясу сервера. Поля: минута 0, час 0, любой день месяца, любой месяц, любой день недели. Эквивалент макросов @daily или @midnight. Чтобы зафиксировать часовой пояс, добавьте CRON_TZ=America/New_York в начале crontab.
Как запустить cron-задачу каждые 30 секунд?
Со стандартным POSIX cron — никак: минимальная гранулярность — одна минута. Три обходных пути: две сдвинутые задачи * * * * *, у одной из которых sleep 30 &&; systemd-таймер с OnCalendar=*:*:0/30; или долгоживущий воркер, спящий между итерациями. Последний обычно и есть правильный ответ.
Какой часовой пояс cron использует по умолчанию?
Локальный системный часовой пояс сервера (/etc/timezone или переменная окружения TZ). Cron на 9 утра на UTC-сервере сработает в 4 утра по восточному США. Решение: задайте CRON_TZ= в начале crontab или переведите серверы на UTC и проектируйте расписания в UTC. GitHub Actions всегда в UTC; Kubernetes 1.27+ поддерживает spec.timeZone.
Почему моя cron-задача не запускается?
Если ваша cron-задача не запускается, проверьте по порядку: запущен ли демон cron (systemctl status cron); задан ли $PATH в crontab; перехватывается ли stderr (>> log 2>&1); загружена ли crontab пользователя (crontab -l); экранирован ли % в командах; тот ли часовой пояс, что вы ожидаете. Большинство отчётов «не запускается» — это второй или третий пункт.
Синтаксис Kubernetes CronJob такой же, как у Linux cron?
В поле расписания — да: оба используют POSIX cron из пяти полей. Kubernetes добавляет spec.timeZone (1.27+), concurrencyPolicy для контроля наложений, startingDeadlineSeconds для восстановления пропущенных запусков и suspend: true для паузы. В Linux cron ничего этого нет, там в ход идут flock и anacron.
В чём разница между @reboot и @daily?
@daily — макрос для 0 0 * * *, то есть каждый день в полночь по фиксированному расписанию. @reboot срабатывает один раз при запуске демона cron, без повторяющегося расписания. @reboot поддерживается vixie cron и cronie, но не Kubernetes CronJob, GitHub Actions и AWS EventBridge. В контейнерах @reboot срабатывает редко.
В чём разница между cron и crontab?
cron — это фоновый демон, выполняющий запланированные задачи; crontab — это файл, в котором они перечислены (а также команда crontab для его редактирования). Демон периодически читает crontab каждого пользователя и запускает команды, время выполнения которых совпадает с cron-выражением. Коротко: cron — движок, crontab — рецепт.