Аннотация
В настоящей статье описывается работа с таймерами systemd — специальными юнитами службы systemd, управляющими запуском других юнитов systemd или программ.
Термины
- Cron — системная служба, запускающая в указанное время перечисленные для неё задания.
- Systemd — системная служба, обеспечивающая управление юнитами в процессе загрузки и функционирования ОС.
Юнит
(
unit
)
— специально оформленный файл конфигурации Systemd . Каждый юнит отвечает за определенную функциональность:- службу (
*.service ); - точку монтирования (
*.mount ); - устройство (
*.device ); - файл подкачки (
*.swap ); - сокет (
*.socket ); - таймер (
*.timer); - и т. д.
Общие особенности юнитов
- Юниты поддерживают выполнение фиксированного набора команд
systemctl ( start, stop, reload, restart и т.д.). - Юниты могут запускаться как от имени суперпользователя (общесистемные юниты), так и от имени непривилегированных пользователей (пользовательские юниты).
- По умолчанию пользовательские юниты существуют только в пределах пользовательских сессий, в которой они созданы, если не разрешена их работа вне пользовательской сессии. Разрешить работу пользовательских приложений вне пользовательских
сессий можно командами:
- для текущего пользователя:
| loginctl enable-linger $USER |
- для других пользователей:
| sudo loginctl enable-linger <имя_пользователя> |
- Для работы с общесистемными юнитами требуются права администратора (используется sudo). Работа с пользовательскими юнитами выполняется с указанием опции --user команды systemctl от имени непривилегированного пользователя .
Служба cron
Служба cron устанавливается при установке ОС и запускается автоматически при загрузке. Служба поддерживает общесистемные и пользовательские таблицы заданий. Редактирование пользовательского списка заданий рекомендуется выполнять при помощи команды: Для работы с общесистемной таблицей заданий можно использовать ту же команду от имени суперпользователя (sudo). Справка по настройке таблиц заданий доступна в man cron. |
Таймеры systemd
Таймеры systemd различаются:
- таймеры реального времени — срабатывают в определенные моменты времени. Аналогичны инструменту
cron, но обладают более гибкими настройками периодов работы; Таймеры реального времени systemd не связаны с RTOS (real-time operating system) |
- монотонные таймеры — срабатывают через заданное время прошедшее с определенного начального момента (определенного события).
- по времени существования:
- постоянные таймеры;
- временные таймеры:
- временные пользовательские таймеры существуют только в пределах пользовательских сессий, в которой они созданы, если не разрешена их работа вне пользовательской сессии.
- временные общесистемные таймеры существуют до перезагрузки ОС.
Различия таймеров и заданий cron
Основные причины для применения таймеров вместо заданий cron : - таймеры используют единую систему команд инструмента управления службами
systemctl; - таймеры имеют встроенные функции для ведения журналов и отслеживания состояния выполнения;
- таймеры могут инициировать выполнение задач на основе событий системы, например запуска или окончания работы службы, вызванной другим таймером, а не только по расписанию как
cron;
- приоритет выполнения таймеров выше, чем у заданий
cron;
-
systemd предотвращает дублирование таймеров; - при совпадении времени запуска заданий
cron эти задания выполняются последовательно, таймеры работают полностью параллельно.
|
Создание таймеров
По умолчанию юниты постоянных системных таймеров
Юниты системных временных таймеров хранятся в каталоге /run/systemd/transient, пользовательских временных таймеров — в каталоге /run/user/<числовой_идентификатор_пользователя>/systemd/transient. Числовой идентификатор пользователя можно получить командой:
Юнит таймера в обязательном порядке содержит ссылку на юнит службы, которую он контролирует.
Systemd имеет несколько зарезервированных системных юнитов, перечень которых доступен по команде man systemd.special
Назначение занятых системных имён создаваемым юнитам нежелательно и приводит к ошибке выполнения создаваемого юнита |
Общая структура юнита
[Unit]
# Имя и описание службы
Description=this is a test example of the service
# Тип службы, указан oneshot, без порождения подпроцессов для упрощения взаимодействия с таймерами
Type=oneshot
[Service]
# Перезапуск при сбое, необязательный параметр
Restart=on-failure
# Пример выполняемой команды
ExecStart=/usr/local/bin/<имя файла или сценария> |
Где:
Example.service — пример названия юнита.
Обязательные параметры:
- Description — краткое описание юнита, в описании допускаются пробелы и кавычки в начале и конце строки с описанием;
- ExecStart — имя исполняемого файла, команды для командной строки, другой службы или сценария.
Общая справка доступна по команде man systemd units. Справка по юнитам служб и параметрам man systemd.service
Юнит таймера реального времени
В юните таймера должно быть указано имя юнита, которым управляет таймер. Для этого используется параметр Unit=<имя_юнита_запускаемой_службы>.service. При этом допускается указание зарезервированных системных служб, перечисленных в man systemd.special.
[Unit]
# Имя и краткое описание таймера
Description=
[Timer]
# Пример для запуска в каждый вечер пятницы
OnCalendar= Fri *-*-* 18:00:00
# Здесь указывается имя юнита службы
Unit=Example.service
# Необязательные параметры
Persistent=true
AccuracySec=1h
WakeSystem=30s
# Необязательная для таймеров секция
[Install]
WantedBy=timers.target
|
Где:
- Unit — обязательный параметр, имя юнита контролируемой службы. Следует различать секцию
[Unit] определяющую параметры юнита таймера и параметр Unit , определяющий юнит, которым будет управлять таймер. - OnCalendar — обязательный параметр для таймеров реального времени, определяющий момент запуска службы из параметра
Unit в указанный интервал. Общий формат задания значения параметра:
OnCalendar=ДеньНедели Год-Месяц-День Час:Минута:Секунда |
Допускается:- пропускать неиспользуемые указания времени;
- указывать символ * в значении "каждый";
- для указания интервалов использовать две точки;
- для перечислений использовать запятые;
- для указания от окончания периода использовать символ ~ вместо символа -.
Подробная справка о формате времени доступна по команде man 7 systemd.time.
Примеры значений параметра:
- каждое 15 число каждого месяца каждого года:
OnCalendar= *-*-15
- каждый день каждого месяца каждого года с понедельника по пятницу, в 7:00:
OnCalendar=Mon..Fri *-*-* 7:00:00 - каждую субботу и воскресенье в 19:00 и в 19:30:
OnCalendar=Sun,Sat *-*-* 19,19:30:00
- если последний день месяца пятница:
OnCalendar=Fri *-*~1
проверить или уточнить формат даты можно командой:
Original form: Mon..Sun Normalized form: *-*-* 00:00:00 Next elapse: Fri 2024-11-29 00:00:00 MSK (in UTC): Thu 2024-11-28 21:00:00 UTC From now: 8h left
|
Где Mon..Sun — интересующий момент времени. |
Для таймеров реального времени допускается указание нескольких параметров OnCalendar с разными интервалами времени и моментами срабатывания |
- Persistent — указание запустить таймер немедленно после старта системы, если предыдущий запуск был пропущен, по умолчанию
false.
- AccuracySec — точность момента запуска таймера. Таймеры будут запускаться в разные моменты времени в пределах указанного диапазона, начиная с указанного времени старта. Этот прааметр предназначен для снижения нагрузки на ресурсы компьютера при одновременном запуске нескольких таймеров. Значение этого параметра по умолчанию — одна минута, что дает соответствующий разброс времени запуска контролируемых таймерами служб. Если такое поведение неприемлемо, то следует уменьшить значение этого параметра.
- WakeSystem — интервал, через который будет осуществлен вывод ОС из режима ожидания (
suspend) после окончания отсчёта времени таймером.
- WantedBy — указывает на целевое состояние при котором запускается данный юнит. Целевое состояние определяется статусом загруженной ОС. Для таймеров по умолчанию задано значение
timers.target.
Перечень целевых состояний доступен по команде:
systemctl list-unit-files --type=target
|
Справка по настройке таймеров доступна по команде man systemd.timer
Юнит монотонного таймера
В юнитах монотонных таймеров указывается событие, от которого начинается отсчет времени срабатывания таймера. Перечень возможных параметров, задающих событие:
- OnBootSec — можно считать, что отсчет времени ведется с момента начала отсчета времени ядром. Контролируемый юнит выполняется однократно. Если при создании таймера указанное время прошло — то контролируемый юнит выполняется немедленно.
- OnStartupSec — отсчет с момента запуска службы systemd. Для системных таймеров параметр близок к параметру OnBootSec, так как системная служба контроля таймеров при загрузке системы стартует как можно раньше. Для пользовательских таймеров отсчет ведется от момента запуска пользовательской службы контроля таймеров, которая запускается при первом входе пользователя. Контролируемый юнит выполняется однократно. Если при создании таймера указанное время прошло — то контролируемый юнит выполняется немедленно.
- OnActiveSec — отсчет от момента активации таймера.
- OnUnitActiveSec — отсчет от старта контролируемого юнита. Для начала отсчета юнит должен быть запущен принудительно.
- OnUnitInactiveSec — отсчет от завершения работы отслеживаемого юнита. Для начала отсчета юнит должен быть запущен принудительно.
- OnClockChange, OnTimezoneChange — при значении
true событием считается изменение показаний системных часов реального времени (CLOCK_REALTIME) относительно показаний монотонных часов (CLOCK_MONOTONIC) или изменение временной зоны.
Перечень значений параметра <интервал> задается указанием временного промежутка (15m — 15 минут, 1h — один час и т.д. ) подробнее см. man systemd.time
Пример юнита монотонного таймера:
[Unit]
# Имя и краткое описание таймера
Description=
[Timer]
# Формат <Событие>=<интервал>. В указанном примере таймер сработает через 50 минут после собственного запуска
OnActiveSec=50minutes
# Здесь указывается имя юнита службы
Unit=Example.service
# Необязательные параметры
Persistent=true
AccuracySec=1h
WakeSystem=30s
# Необязательная для таймеров секция
[Install]
WantedBy=timers.target
|
Запуск и отладка таймера
Перед запуском таймера необходимо:
- Перезагрузить конфигурацию служб
systemd: sudo systemctl daemon-reload
|
- юниты на наличие синтаксических ошибок:
systemd-analyze verify <имя_юнита>.timer # или .service
|
- Запустить таймер:
sudo systemctl start <имя_таймера>.timer
|
Временные таймеры
Временные таймеры управляют выполнением заданных команд. Такие таймеры создаются с помощью команды systemd-run.
sudo systemd-run --<событие>="время" --unit="<название_таймера>" <команда> |
При выполнении команды автоматически создаются:
- юнит службы
<название_таймера> .service ; - юнит таймера
<название_таймера> .timer.
Опции команды:
— одно из событий срабатывания таймера. Используются аналоги событий, задаваемых параметрами постоянных таймеров:
-
— OnBootSec;
--on-startup — OnStartupSec
--on-unit-active
nUnitActiveSec;
--on-unit-inactive — OnUnitInactiveSec;
--on-calendar — OnCalendar.
Пример:
: Running timer as unit: run-r81fc2842fa884a639d020dea5faabb9d.timer Will run service as unit: run-r81fc2842fa884a639d020dea5faabb9d.service
|
Где *:0/1 - время выполнения (каждую минуту) , справка по формату времени см.
Содержимое текстового файла с записями: Пн 11 ноя 2024 10:03:00 MSK
Пн 11 ноя 2024 10:04:00 MSK
Пн 11 ноя 2024 10:05:00 MSK
Пн 11 ноя 2024 10:06:00 MSK
Пн 11 ноя 2024 10:07:00 MSK
Пн 11 ноя 2024 10:08:00 MSK
Пн 11 ноя 2024 10:09:00 MSK
Пн 11 ноя 2024 10:10:00 MSK |
|
Принудительный останов временного таймера:
systemctl --user stop run-r81fc2842fa884a639d020dea5faabb9d.timer
|
Управление таймерами
Для получения информации и пользовательских таймерах следует использовать опцию --user.
Пуск, автозапуск, перезапуск, останов, отключение аналогичны командам systemctl для служб. Справка доступна по команде man systemctl, краткая по systemctl -h
Просмотр журналов юнитов
Посмотреть записи журнала конкретного юнита:
sudo journalctl -b -u <имя_юнита> # .service или .timer, параметр -b ограничивает вывод записей текущей загрузкой |
Чтобы ограничить вывод записей определенным интервалом, используется параметры -S и -U (от и до), пример:
sudo journalctl -S "2024-11-03 07:00:00" -U "2024-11-07 07:15:00" -u anacron.timer # имя юнита для примера
|
Anacron это вспомогательный инструмент cron для запуска пропущенных cron во время отключения компьютера заданий.
Следует различать параметры -u (юнит) и -U (до) |
или конкретным интервалом (пример - день назад):
sudo journalctl -S -1d -u anacron.timer
|
Справка доступна по команде man journalctl
, краткая справка по параметрам - journalctl -h
Начиная с очередного обновления 1.7 в Astra Linux Special Edition просмотр журналов юнитов возможен из графического интерфейса через Журнал аудита.