Вопрос или проблема
В продолжение темы Запланировать задачу каждые 20 дней,
Это необходимо для продления, поэтому можно сделать это раньше 20 дней. Но я делаю это с моего ноутбука, который большую часть времени находится в режиме сна. Поэтому гарантированное выполнение – это необходимо (я читал, что у cron этого нет).
Я выбрал systemd.timer вместо cron, так как у меня было впечатление, что “он будет работать даже когда запланированное время пройдет во время того, как система будет в спящем режиме, после ее пробуждения”
Однако, как оказалось, это не так для меня.
Согласно его справочной странице, единственный близкий вариант – это Persistent=
:
Принимает логический аргумент. Если истинно, время, когда единица службы была последний раз запущена, сохраняется на диске. Когда таймер активируется, единица службы срабатывает немедленно, если она должна была сработать хотя бы раз в то время, когда таймер был неактивен. Тем не менее, такое срабатывание подлежит задержке, накладываемой RandomizedDelaySec=. Это полезно, чтобы компенсировать пропущенные запуски службы, когда система была выключена. Обратите внимание, что эта настройка действует только на таймеры, настроенные с помощью OnCalendar=.
Однако я только что осознал, что использую OnUnitActiveSec=20d
вместо необходимого OnCalendar=
, так что наличие Persistent=true
не поможет в моем случае Запланировать задачу каждые 20 дней, верно?
Можно ли для systemd.timer
компенсировать пропущенные запуски служб, запланированные с помощью OnUnitActiveSec=
, после того как компьютер проснулся из режима сна?
PS. Все мои пакеты systemd:
libpam-systemd:amd64_249.11-0ubuntu3.6
libsystemd0:amd64_249.11-0ubuntu3.6
python3-systemd_234-3ubuntu2
systemd_249.11-0ubuntu3.6
systemd-sysv_249.11-0ubuntu3.6
systemd-timesyncd_249.11-0ubuntu3.6
К сожалению, вы обнаружили недостаток таймеров systemd.
Вы можете обойтись несколькими строками OnCalendar=
, создавая свое собственное расписание на год. Это будет неточно в высокосные годы и во время конца года.
OnCalendar=*-01-08
OnCalendar=*-01-28
OnCalendar=*-02-17
OnCalendar=*-03-09
OnCalendar=*-03-29
OnCalendar=*-04-18
OnCalendar=*-05-08
OnCalendar=*-05-28
OnCalendar=*-06-17
OnCalendar=*-07-07
OnCalendar=*-07-27
OnCalendar=*-08-16
OnCalendar=*-09-05
OnCalendar=*-09-25
OnCalendar=*-10-15
OnCalendar=*-11-04
OnCalendar=*-11-24
OnCalendar=*-12-14
Ответ или решение
К сожалению, в вашем случае нельзя программировать выполнение таймера systemd по заданию OnUnitActiveSec=
, чтобы он «догонял» пропущенные запуски задач после выхода системы из спящего режима. Проблема связана с тем, что этот тип настройки ограничивает вас лишь по времени, в то время как желаемая функциональность требует выполнения задач по более сложному расписанию, например, каждые 20 дней.
Чтобы обеспечить выполнение задачи при пробуждении системы, вам нужно использовать опцию OnCalendar=
и установить Persistent=true
. Давайте рассмотрим, как можно настроить systemd.timer для решения вашей задачи с учётом всех приведенных вами деталей.
Создание таймера systemd для выполнения задачи каждые 20 дней
1. Настройка службы (service)
Сначала создайте файл службы, которая будет исполнять необходимую задачу. Например, создадим файл /etc/systemd/system/my-task.service
:
[Unit]
Description=My Task Service
[Service]
Type=oneshot
ExecStart=/path/to/your/script.sh
Не забудьте заменить /path/to/your/script.sh
на фактический путь к вашему скрипту или исполняемой программе.
2. Настройка таймера (timer)
Теперь создайте файл таймера /etc/systemd/system/my-task.timer
:
[Unit]
Description=Runs my task every 20 days
[Timer]
OnCalendar=*:0/20
Persistent=true
[Install]
WantedBy=timers.target
Объяснение конфигурации:
- *`OnCalendar=:0/20`**: Эта настройка позволяет таймеру срабатывать каждые 20 дней. Обратите внимание, что здесь мы использовали конструкцию OnCalendar, которая позволяет системе корректно отслеживать время.
Persistent=true
: Эта опция позволяет таймеру запускать службу немедленно после пробуждения системы, если таймер сработал, пока система была выключена или спала.
Активируем таймер
После настройки таймера не забудьте активировать и запустить его:
sudo systemctl enable my-task.timer
sudo systemctl start my-task.timer
Проверка состояния
Чтобы убедиться, что таймер работает правильно, вы можете использовать следующие команды:
systemctl list-timers --all
Эта команда покажет все активные таймеры и будет включать в себя данные о следующем срабатывании вашего таймера.
Заключение
Используя указанные выше шаги, вы сможете настроить systemd.timer таким образом, чтобы он «догонял» пропущенные запуски после пробуждения системы. Использование опции OnCalendar=
в сочетании с Persistent=true
обеспечит вашу задачу регулярным выполнением даже в ситуациях, когда ваша система находится в спящем режиме. Это решение является более надежным и гибким, чем использование опции OnUnitActiveSec=
. Если у вас возникнут дополнительные вопросы по настройке, пожалуйста, дайте знать!