systemd timers в Linux

systemd timers в Linux

systemd timers в Linux

В предыдущих материалах мы разобрали два классических способа запуска задач по расписанию:

1
2
cron → регулярные задачи
at   → одноразовые задачи

Но в современных Linux-системах на базе systemd есть ещё один механизм:

1
systemd timers

Systemd timer позволяет запускать сервисы по времени или через определённые интервалы и управлять ими привычными инструментами systemd.

В этой статье разберём:

  • что такое systemd timer;
  • как связаны .timer и .service;
  • как посмотреть существующие timers;
  • как создать собственный timer;
  • как работает OnCalendar;
  • что такое OnBootSec и OnUnitActiveSec;
  • зачем нужен Persistent=true;
  • как проверять расписание;
  • как смотреть логи выполнения;
  • как запускать одноразовые timers через systemd-run;
  • чем systemd timers отличаются от cron.

Что такое systemd timer

Systemd timer — это специальный unit-файл systemd, который запускает другой unit по расписанию.

Чаще всего timer запускает соответствующий .service.

Например:

1
2
3
4
5
backup.timer
      ↓
backup.service
      ↓
backup.sh

То есть timer отвечает за вопрос:

Когда запускать?

А service отвечает:

Что запускать?

Это важное отличие от cron, где расписание и команда обычно записываются одной строкой.


Как связаны .timer и .service

По умолчанию systemd связывает timer и service с одинаковым именем.

Например:

1
backup.timer

будет запускать:

1
backup.service

Поэтому обычно создаётся пара файлов:

1
2
/etc/systemd/system/backup.service
/etc/systemd/system/backup.timer

Схема получается такой:

1
2
3
4
5
6
7
backup.timer
      ↓
расписание
      ↓
backup.service
      ↓
команда или скрипт

При необходимости timer может запускать unit с другим именем, но для начала удобнее придерживаться одинаковых названий.


Как посмотреть существующие timers

Systemd уже использует timers для различных системных задач.

Посмотреть активные таймеры можно командой:

1
systemctl list-timers

Пример вывода:

1
2
NEXT                        LEFT       LAST                        PASSED      UNIT
Tue 2026-11-03 23:30:00    20min      Tue 2026-11-03 22:30:00    40min ago   example.timer

Здесь можно увидеть:

1
2
3
4
5
NEXT    → когда будет следующий запуск
LEFT    → сколько осталось
LAST    → когда timer запускался последний раз
PASSED  → сколько прошло времени
UNIT    → имя timer unit

Чтобы показать в том числе неактивные timer units:

1
systemctl list-timers --all

Это одна из самых полезных команд при работе с systemd timers.


Создаём первый systemd service

Сначала создадим сервис.

Например:

1
sudo nano /etc/systemd/system/mytask.service

Содержимое:

1
2
3
4
5
6
[Unit]
Description=My scheduled task

[Service]
Type=oneshot
ExecStart=/usr/local/bin/mytask.sh

Здесь:

1
Type=oneshot

означает, что сервис выполняет одну задачу и завершается.

А:

1
ExecStart=

указывает команду или скрипт.


Создаём тестовый скрипт

Например:

1
sudo nano /usr/local/bin/mytask.sh

Добавим:

1
2
3
#!/bin/bash

echo "Timer выполнен: $(date)" >> /tmp/mytimer.log

Дадим права:

1
sudo chmod +x /usr/local/bin/mytask.sh

Проверим вручную:

1
sudo /usr/local/bin/mytask.sh

Посмотрим результат:

1
cat /tmp/mytimer.log

Если появилась строка с текущей датой, скрипт работает.


Проверяем service вручную

До создания timer полезно убедиться, что сам сервис запускается.

Обновим конфигурацию systemd:

1
sudo systemctl daemon-reload

Запустим сервис:

1
sudo systemctl start mytask.service

Проверим:

1
systemctl status mytask.service

И посмотрим наш лог:

1
cat /tmp/mytimer.log

Если service работает вручную, можно переходить к timer.


Создаём .timer

Теперь создадим:

1
sudo nano /etc/systemd/system/mytask.timer

Например:

1
2
3
4
5
6
7
8
9
[Unit]
Description=Run mytask every day

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Теперь у нас есть два файла:

1
2
mytask.service
mytask.timer

Timer будет запускать service.


OnCalendar

OnCalendar задаёт календарное расписание.

Например:

1
OnCalendar=daily

означает запуск каждый день.

Можно использовать:

1
OnCalendar=hourly

или:

1
OnCalendar=weekly

Но можно указывать и конкретное расписание.

Например:

1
OnCalendar=*-*-* 02:00:00

Это запуск каждый день в 02:00.


Каждый день в 09:30

1
OnCalendar=*-*-* 09:30:00

По будням

Например:

1
OnCalendar=Mon..Fri 09:00

Timer будет запускаться с понедельника по пятницу в 09:00.


Как проверить выражение OnCalendar

Одна из очень удобных возможностей systemd:

1
systemd-analyze calendar

Например:

1
systemd-analyze calendar "*-*-* 02:00:00"

Команда покажет, как systemd понимает расписание и когда наступит следующий запуск.

Ещё пример:

1
systemd-analyze calendar "Mon..Fri 09:00"

Это намного удобнее, чем гадать, правильно ли написано выражение.


Запускаем timer

После создания файлов:

1
sudo systemctl daemon-reload

Теперь включим timer:

1
sudo systemctl enable --now mytask.timer

Здесь:

1
2
3
enable → запускать timer автоматически после загрузки

--now  → запустить timer прямо сейчас

Проверяем:

1
systemctl status mytask.timer

Проверяем timer в списке

1
systemctl list-timers

Ищем:

1
mytask.timer

Можно сразу отфильтровать:

1
systemctl list-timers mytask.timer

Теперь мы можем увидеть время следующего запуска.


Как остановить timer

Остановить:

1
sudo systemctl stop mytask.timer

Отключить автозапуск:

1
sudo systemctl disable mytask.timer

Сразу остановить и отключить:

1
sudo systemctl disable --now mytask.timer

Persistent=true

Одна из полезных возможностей календарных systemd timers:

1
Persistent=true

Представим timer:

1
OnCalendar=daily

который должен выполняться каждый день в 02:00.

Но компьютер в это время был выключен.

При обычном расписании запуск будет пропущен.

С:

1
Persistent=true

systemd запоминает предыдущие срабатывания timer.

Если во время простоя системы должен был произойти запуск, после следующей активации timer systemd может выполнить пропущенную задачу.

Это особенно удобно для:

  • ноутбуков;
  • рабочих станций;
  • серверов, которые периодически выключаются;
  • резервного копирования;
  • задач обслуживания.

Важно: Persistent= относится к timers, использующим OnCalendar=.


OnBootSec

Не все timers привязаны к часам и календарю.

Можно запускать задачу через определённое время после загрузки системы.

Например:

1
2
[Timer]
OnBootSec=5min

Это означает:

1
запустить задачу через 5 минут после загрузки

OnUnitActiveSec

Можно запускать задачу через определённый интервал после предыдущего запуска.

Например:

1
2
3
[Timer]
OnBootSec=5min
OnUnitActiveSec=30min

Логика:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
загрузка системы
      ↓
5 минут
      ↓
первый запуск
      ↓
30 минут
      ↓
следующий запуск
      ↓
30 минут
      ↓
следующий запуск

Так можно создавать периодические задачи без календарного расписания.


Calendar timers и monotonic timers

У systemd timers есть два основных подхода к расписанию.

Календарное время

Используем:

1
OnCalendar=

Например:

1
OnCalendar=*-*-* 02:00:00

Это означает:

каждый день в два часа ночи.


Интервал относительно события

Используем:

1
2
3
4
OnBootSec=
OnActiveSec=
OnUnitActiveSec=
OnUnitInactiveSec=

Например:

1
OnBootSec=10min

означает:

через десять минут после загрузки.

А:

1
OnUnitActiveSec=1h

означает:

через час после предыдущей активации unit.


Где смотреть логи

Одна из сильных сторон systemd timers — интеграция с journal.

Сам timer:

1
journalctl -u mytask.timer

Сервис:

1
journalctl -u mytask.service

Последние события:

1
journalctl -u mytask.service -n 50

Следить в реальном времени:

1
journalctl -u mytask.service -f

Это удобно при поиске ошибок.


Проверяем состояние service

1
systemctl status mytask.service

Проверяем timer:

1
systemctl status mytask.timer

И список timers:

1
systemctl list-timers

Получается удобный набор диагностики:

1
2
3
systemctl status
systemctl list-timers
journalctl

Если изменили .timer или .service

После редактирования unit-файлов нужно сообщить systemd об изменениях:

1
sudo systemctl daemon-reload

После этого можно перезапустить timer:

1
sudo systemctl restart mytask.timer

Это важный шаг, о котором часто забывают.


Одноразовая задача через systemd-run

Необязательно всегда вручную создавать .service и .timer.

Для временных задач есть:

1
systemd-run

Например:

1
systemd-run --on-active=5m /usr/local/bin/mytask.sh

Systemd создаст временные timer и service units.

Посмотреть их можно через:

1
systemctl list-timers

Запуск по календарю через systemd-run

Можно использовать:

1
systemd-run --on-calendar="tomorrow" /usr/local/bin/mytask.sh

Таким образом systemd-run позволяет быстро создать задачу по расписанию без постоянных unit-файлов.

Это в некотором смысле похоже на использование at, но уже через инфраструктуру systemd.


Cron или systemd timers

Один из главных вопросов:

Нужно ли теперь отказываться от cron?

Нет.

У обоих вариантов есть свои преимущества.

Cron

Простой пример:

1
0 2 * * * /home/user/backup.sh

Плюсы:

  • простой;
  • привычный;
  • короткая запись;
  • работает на огромном количестве Unix/Linux-систем;
  • отлично подходит для небольших периодических задач.

Systemd timer

Здесь обычно есть:

1
2
backup.timer
backup.service

Плюсы:

  • интеграция с systemctl;
  • логи через journalctl;
  • зависимости между units;
  • управление окружением и пользователем через service unit;
  • Persistent=true;
  • календарные и относительные timers;
  • единая система управления сервисами и задачами.

Что выбрать

Для простой задачи:

1
каждый день запустить небольшой скрипт

cron может быть самым простым решением.

Если задача уже является частью инфраструктуры systemd, нужны зависимости, журналирование, контроль состояния и более гибкое управление — systemd timer часто оказывается удобнее.

Поэтому правильнее думать не:

systemd timers заменили cron.

А:

это два разных инструмента для похожих задач.


Cron, at и systemd timers

Теперь наш блок планирования задач можно собрать полностью.

cron

1
регулярные задачи

Например:

1
2
3
каждый день
каждые 5 минут
по понедельникам

at

1
одноразовая задача

Например:

1
2
3
через 20 минут
сегодня в 23:00
завтра утром

systemd timers

1
задачи, интегрированные с systemd

Например:

1
2
3
запустить service каждый день
через 5 минут после загрузки
каждые 30 минут после предыдущего запуска

Практический пример целиком

Создаём service:

1
sudo nano /etc/systemd/system/backup.service
1
2
3
4
5
6
[Unit]
Description=Backup task

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

Создаём timer:

1
sudo nano /etc/systemd/system/backup.timer
1
2
3
4
5
6
7
8
9
[Unit]
Description=Run backup every day

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target

Обновляем systemd:

1
sudo systemctl daemon-reload

Включаем:

1
sudo systemctl enable --now backup.timer

Проверяем:

1
systemctl list-timers

Смотрим состояние:

1
systemctl status backup.timer

Логи:

1
journalctl -u backup.service

Готово.


Краткая шпаргалка systemd timers

Посмотреть timers:

1
systemctl list-timers

Все timers:

1
systemctl list-timers --all

Проверить timer:

1
systemctl status mytask.timer

Запустить:

1
sudo systemctl start mytask.timer

Включить и запустить:

1
sudo systemctl enable --now mytask.timer

Остановить:

1
sudo systemctl stop mytask.timer

Перечитать unit-файлы:

1
sudo systemctl daemon-reload

Проверить календарное выражение:

1
systemd-analyze calendar "Mon..Fri 09:00"

Посмотреть логи:

1
journalctl -u mytask.service

Создать временный timer:

1
systemd-run --on-active=5m /usr/local/bin/mytask.sh

Что важно знать для LPIC-1

Systemd timers входят в тему LPIC-1 Objective 107.2 — автоматизация административных задач по расписанию.

В рамках этой темы важно понимать:

1
2
3
4
5
cron
at
systemd timers
systemctl
systemd-run

Для systemd timers полезно уметь:

  • понимать назначение .timer unit;
  • понимать связь .timer и .service;
  • посмотреть timers;
  • запустить и включить timer;
  • понимать принцип календарного и интервального расписания.

Что стоит запомнить

Самая важная схема:

1
2
3
4
5
.timer
  ↓
.service
  ↓
команда или скрипт

Основные команды:

1
2
3
4
5
6
systemctl list-timers
systemctl status name.timer
systemctl enable --now name.timer
journalctl -u name.service
systemd-analyze calendar
systemd-run

И основные параметры:

1
2
3
4
OnCalendar=
OnBootSec=
OnUnitActiveSec=
Persistent=true

Не нужно запоминать весь синтаксис systemd timers.

Гораздо важнее понимать принцип и знать, где проверить расписание и состояние задачи.


Презентация и видео по теме

Скачать презентацию

➡️Rutube

➡️VK

➡️YouTube


Документация

Авторский пост защищен лицензией CC BY 4.0.

© solizarevich. Некоторые права защищены.

Использует тему Chirpy для Hugo

Популярные теги