Systemd-timers как способ запускать своих скриптов в нужное время. Можно конечно пользоваться старым
добрым cron, но таймеры гибче позволяют настроить время и периодичность запуска.
Почему
Для периодического запуска скриптов есть cron, но у него есть несколько проблем, которые могут мешать:
- крон может быть только периодическим, не получится полноценно описать “календарный” или событийный вариант запуска ( разве что внутри скрипта проверять дату-вермя);
 - крон срабатывает раз в минуту, то есть минимальный период времени - 1 минута (есть всякого уровня “хаки”, вроде вызова
с предварительным 
sleep 15, но это хаки); - крон просто запускает скрипт, as is (проверка того что скрипт еще работает, все то что можно сделать в декларативной форме в unit-файле systemd - нужно делать самому);
 - крон скрипты не умеют в “зависимости”;
 - крон скрипты обычно хранятся внутри 
/etc, а не все могут туда писать. 
Может еще есть какие мелочи, но это те ограничения с которыми приходилось сталкиваться. Для таймеров же для меня есть два основных недостатка:
- необходимо два разных файла (unit - что выполнить, timer - когда выполнить), за исключением временных задач;
 - нет отправки email уведомлений (
EMAILTOизcron), тут нужно подумать об этом самому. 
Для меня минусы не столь значительны и перекрываются плюсами. Поэтому приступим.
Хранение таймеров
Итак, что бы создать timer - нужен unit файл. Как он создается, какой он может быть и тд оставим за рамками этого
текста. Для нашего пример это будет task.service. Таймеры по месту хранения будут двух типов.
Проверить таймеры в системе
Начнем с того, что таймеров есть два списка: системный и пользовательский. Вызов для работы с ними отличается
использованием или не использованием ключа --user.
Для просмотра всех таймеров в системе можно воспользоваться командой (для всех таймеров текущего пользователя добавить
ключ --user):
 |  | 
В полученной таблице будут следующие столбцы:
NEXT- дата и время следующего запуска таймера;LEFT- время до следующего запуска таймера;LAST- дата и время последнего запуска таймера;PASSED- время с последнего запуска таймера;UNIT- имяtimer-файла;ACTIVATES- имяunit-файла для запуска.
По умолчанию имя timer и unit файлов должны быть одинаковыми (за исключением этих суффиксов), но есть возможность
указать кастомное имя timer-файла и привязать его к стандартному unit-файлу. Пример такой записи:
 |  | 
Где искать файлы
Все таймеры хранятся в 3 основных местах:
/lib/systemd/system- “встроенные” таймеры;/etc/systemd/system- кастомные системные таймеры;~/.config/systemd/user- кастомные таймеры пользователя.
Типы таймеров по времени запуска
По времени запуска есть два типа таймеров:
Realtime timers- таймеры реального времени привязанные к датам;Monotonic timers- монотонные таймеры привязанные к периодам времени.
При работе с таймерами нужно иметь в виду, что со временем в системе могут происходить разного рода особенности, например:
- сон компьютера, при этом время не останавливается;
 - может поменяться временная зона;
 - само время может “ускорится” или “замедлиться” для синхронизации.
 
Таймеры реального времени
В таймере реального времени главный параметр - OnCalendar внутри блока [Timer]. Параметры может быть:
OnCalendar=daily- ежедневный запуск (в 00:00:00);OnCalendar=monday *-10-* 17:00- каждый понедельник октября в 17 часов;OnCalendar=08:00:00- каждый день в 8 утра.
Полное описание формата можно посмотреть в systemd.time(7). Для локального тестирования можно воспользоваться командой:
 |  | 
Ответ получается такого вида:
 |  | 
Так же для такого типа таймера есть несколько вспомогательных параметров (основные для использования мной):
Persistent- значениеtrueилиfalse, при отсутствии времени предыдущего запуска сразу запускает таймер;RandomizedDelaySec- позволяет задать “промежуток” времени в который можно выполнить таймер, если на одно и то же время ставится много таймеров, то это позволяет “размазать” их запуск по этому промежутку;FixedRandomDelay- “запоминает” промежуток для таймера с параметром выше;AccuracySec- это попытка “собрать похожие по времени таймеры”, что не “будить” процессор лишний раз. По умолчанию значение здесь 1 минута, для рандомизированно запущенных таймеров лучше всего проставить значение1us.
Монотонные таймеры
Основные параметры монотонных таймеров:
OnActiveSec- период времени с момента активации таймера;OnBootSec- время после загрузки (для контейнеров этот параметр будет эквивалентомOnStartupSec), не работает для пользовательских таймеров;OnStartupSec- время со старта сервис-менеджера, для системных таймеров очень близок кOnBootSec, для контейнеров - это время запуска контейнера, для пользователя - время входа в систему;OnUnitActiveSec- определяет промежуток времени с последней активации таймера, в который таймер должен быть повторно активирован (если за сеанс нужно выполнять задачу несколько раз);OnUnitInactiveSec- то же самое что выше, но учитывает время деактивации.
Дополнительные же параметры тут такие:
OnClockChange- выполнить таймер при смещении времени (синхронизация, установка времени руками);OnTimezoneChange- выполнить таймер при изменении часового пояса.
Пример из моей жизни
Подгрузка базы паролей pass
У pass, который используется для хранения паролей, есть возможность хранить БД под
версионированием в git. Но стандартные механизмы умеют только автоматом пушить изменения. Так как у меня есть несколько
машин, нужно время от времени эти изменения на каждую из них пулить. Для этого был написан простой скрипт и запущен
таймер по нему, который через минуту после включения пулит свежую БД для pass, и далее проверяет обновления каждые 8
часов.
 |  | 
Отложенный старт Docker
Появилась необходимость отсрочить старт сервиса Docker (и всех контейнеров). Для этого всего лишь убрал сервис докера из автозагрузки:
 |  | 
И добавил таймер для запуска Docker через 5 минут после загрузки системы.
 |  | 
Таймер для certbot идущий в комплекте с пакетом
Запускается каждый день два раза в сутки в произвольное время в пределах от 00:00 до 12:00 и от 12:00 до 00:00.
 |  |