Как запускать cron-задачу каждые 30 секунд

Обновлено 6 ноября 2026

Cron не умеет запускать что-либо чаще раза в минуту: самое мелкое поле строки crontab — минута. Но есть несколько надёжных способов запускать задачу каждые 30, 15 или 10 секунд. Какой подойдёт, зависит от того, сколько длится задача и можно ли двум запускам накладываться.

Две строки crontab со sleep

Самый частый приём: запускать задачу в начале каждой минуты и ещё раз через 30 секунд.

* * * * * /srv/poll.sh
* * * * * sleep 30; /srv/poll.sh

Это просто и переживает перезагрузки, как любая задача cron. Второй запуск стартует через 30 секунд после начала минуты, а не через 30 секунд после конца первого, поэтому если poll.sh может идти дольше 30 секунд, одновременно окажутся две копии. Это предотвращает flock:

* * * * * flock -n /tmp/poll.lock /srv/poll.sh
* * * * * sleep 30; flock -n /tmp/poll.lock /srv/poll.sh

С -n вторая копия сразу сдаётся, а не ждёт, так что запуски пропускаются, а не копятся в очереди.

Цикл внутри минуты

Для 15 или 10 секунд строк становится слишком много. Используйте цикл:

# каждые 15 секунд
* * * * * for i in 1 2 3 4; do /srv/poll.sh; sleep 15; done

Здесь каждый запуск начинается после окончания предыдущего плюс 15 секунд, так что медленный запуск сдвигает следующие. Если цикл не укладывается в минуту, он накладывается на цикл следующей минуты. Для быстрых задач это нормально, для медленных — повод выбрать другой способ.

Таймер systemd

Таймеры systemd понимают секунды напрямую и никогда не запускают сервис, который ещё работает:

# /etc/systemd/system/poll.timer
[Timer]
OnBootSec=30s
OnUnitActiveSec=30s
AccuracySec=1s

[Install]
WantedBy=timers.target

AccuracySec=1s важен: по умолчанию systemd может задержать срабатывание таймера до минуты ради экономии энергии, и интервал в 30 секунд теряет смысл. Сам сервис — обычный юнит Type=oneshot; полный пример с пингами об успехе и ошибке — в гайде по таймерам systemd.

Постоянно работающий процесс

Если задача запускается каждые несколько секунд, запуск нового процесса каждый раз стоит дороже самой работы. Небольшой цикл, который поддерживает systemd, Docker или Kubernetes, часто чище:

#!/bin/sh
while true; do
  /srv/poll.sh
  sleep 30
done

Запускайте его с Restart=always в сервисе systemd или с restart: unless-stopped в Docker Compose. Тогда за тем, чтобы он работал, следит супервизор процессов, а не cron.

Что выбрать

СпособПодходит дляНа что смотреть
Две строки со sleepБыстрых задач каждые 30 секундНаложения без flock
Цикл в одной строкеБыстрых задач каждые 10–20 секундСдвиг и наложения при медленном запуске
Таймер systemdЛюбого интервала, без наложенийЗадайте AccuracySec
Постоянный процессЗапусков каждые несколько секундНужен супервизор, который его перезапустит

Мониторинг задачи, которая запускается так часто

Задача, которая запускается каждые 30 секунд, громко падает, когда падает, но может и просто остановиться: таймер выключили, процесс умер, сервер пересоздали и забыли восстановить crontab. Пульс ловит всё это. Пинг на каждый запуск не нужен: одного пинга в минуту достаточно, чтобы знать, что задача жива.

В Heartcron создайте проверку с периодом в 1 минуту и коротким запасом времени и отправляйте пинг только из первой строки crontab:

heartcron checks create poller --every 1m --grace 2m

* * * * * flock -n /tmp/poll.lock /srv/poll.sh && curl -fsS -m 10 --retry 3 https://ping.heartcron.com/<uuid> > /dev/null
* * * * * sleep 30; flock -n /tmp/poll.lock /srv/poll.sh

Если пинги пропадут больше чем на три минуты, придёт алерт на почту, в Telegram, Slack или Discord. Все сигналы, включая /fail для ошибок, — в документации. Для расписаний от минуты и реже расшифровщик cron-выражений точно покажет, когда сработает строка.

Другие руководства