Systemd.timer. Запуск задач по расписанию

10/23/2015

Чтобы SystemD принял во внимание то, что у него есть сервис, который он должен запускать по таймеру, у сервиса должен быть соответствующий unit-файл (файл конфигурации службы для SystemD), он должен лежать в правильном месте, иметь расширение ".service" и быть доступным на чтение, а также специальный одноименный unit-файл, но с расширением ".timer", описывающий, соответственно, когда указанный сервис должен быть запущен. Также желательно, чтобы в один и тот же момент времени у того же самого сервиса не было соответствующего ему init-скрипта - скрипта, который запускала служба init (когда еще была актуальна), для избежания конфликтов - многие системные администраторы все еще по привычке лезут в каталог /etc/init.d/ в поисках этих самых скриптов. Освоив systemd.timer, вы вполне сможете отказаться от CRON и ANACRON - синхронного и, соответственно, асинхронного планировщиков под Linux, освободив системные ресурсы для чего-то более важного.

Итак приступим. Для примера создадим простенький скрипт на языке командного интерпретатора bash, который выполнит архивирование со сжатием домашнего каталога пользователя, например, begemot, который располагается в /home, а затем отправит архив на бэкап сервер, используя утилиту ncat. Не будем его больше ничем перегружать - он нам нужен только для демонстрации:

#!/bin/bash
tar -cz /home/begemot | ncat 10.1.14.72 7000

Что мы здесь видим: запускается bash, вызывает tar, который создает архив папки /home, перенаправляя вывод gzip'у для сжатия данных, который уже в свою очередь передает уже сжатый поток данных ncat'у в направлении порта 7000 сервера с IP 10.1.14.72. Чтобы вся это кухня заработала, на той стороне должен стоят такой же ncat и принимать это всё с 7000-ого порта, но это тема для другой статьи. Сейчас нам нужно создать unit-файл описывающий данный сервис. Условимся, что скрипт мы положили в /opt, назвали его home_backup и, конечно, не забыли дать ему право на исполнение командой

chmod +x /opt/home_backup

А вот и содержание самого unit-файла, который нужно положить в /lib/systemd/system с названием, например, home_backup.service

[Unit]
Description=Backup script for /home/begemot
 
[Service]
ExecStart=/opt/home_backup

Обратить внимание здесь можно разве что на директиву ExecStart, которая описывает, что будем запускать, Description - это простое описание, не более. Наконец, чтобы активировать механизм systemd.timer осталось создать unit-файл типа timer и положить туда же с тем же названием, сменив только расширение с ".service" на ".timer"

[Unit]
Description=timer for home_backup script
 
[Timer]
OnCalendar=02:50
 
[Install]
WantedBy=timers.target

Здесь стоит обратить внимание на директиву "OnCalendar", которая показывает, что запускать сервис надо "по календарю" и, поскольку, ничего иного не указано, в 02:50 ночи. Ничего - не значит ничего, на самом деле SytemD просто остальные переменные сам заменит на "*", означающую "всегда" - точно так же, как и в терминологии CRON. Иными словами всегда, но только в 02:50, а 02:50 встречается в сутках только раз, поэтому это задание будет выполняться каждый день в 02:50. Какие еще вариации можно туда писать? Приведем несколько примеров, описанных в документации к SystemD:

Пн-Вт,СБ и ВС в 00:00:00
Sat,Thu,Mon-Wed,Sat-Sun

Все Пн и Вс в 2016-ом в 01:23 и в 02:23
Mon,Sun 16-*-* 2,1:23

1-ого числа каждого месяца, но только если это среда в 00:00:00
Wed *-1

То же самое
Wed-Wed,Wed *-1

По средам 17:48:00
Wed, 17:48

15-ого октября 2016-ого в 01:02:03, но только, если это Вт, Ср, Чт, Пт, Сб
Wed-Sat,Tue 12-10-16 1:2:3

7-ого числа каждого месяца в 00:00
 *-*-7 0:0:0

Каждый год 15-ого октября в 00:00
*-10-15 00:00:00

Каждой 5-ое марта в 08:05:40
03-05 08:05:40

Ежедневно в 08:05:40
08:05:40

Ежедневно в 5:40
*-*-* 05:40:00

В 2016-ом 3-его мая в 00:00
2003-03-05

Ежегодно 3-его мая в 00:00
03-05

Ежечастно в 0 минут
hourly

Ежедневно в 00:00
daily

Ежемесяно 1-ого числа в 00:00
monthly

Еженедельно в понедельник в 00:00
weekly

Ежегодно 1-ого января в 00:00
yearly

Тоже самое
annually

Как видите, очень гибко. Практически любую вариацию можно легко настроить. "OnCalendar=" также можно комбинировать с другими типами таймеров, например "OnActiveSec=" задает время в секундах, которое должно пройти после активации timer файла, чтобы единовременно запустился указанный сервис. "OnBootSec=" делает то же самое, но отправной точкой является момент времени, когда компьютер был заружен. Осталось только понять зачем нужна директива "WantedBy=timers.target". На сам сервис она никак не влияет - она нужна для того, чтобы при следующей перезагрузке, наш таймер поднялся автоматически. Поэтому командой

systemctl daemon-reload

перечитываем конфигурацию SystemD. Командой

systemctl enable home_backup.timer

говорим SystemD не забыть его включить при следующей перезагрузке. И наконец, перезагрузившись, или руками включаем таймер

systemctl start home_backup.timer

Всё! Systemd.timer будет отслеживать системные часы и по наступлению нужного момента запустит нужный сервис.

Темы:

Добавить комментарий