arch-wiki-md-repo
Version:
All arch-wiki articles in markdown format, updated every two days.
231 lines (150 loc) • 21.5 kB
Markdown
Ссылки по теме
* [systemd (Русский)](/index.php/Systemd_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9) "Systemd (Русский)")
* [systemd/Пользователь](/index.php/Systemd/%D0%9F%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C "Systemd/Пользователь")
* [systemd FAQ](/index.php/Systemd_FAQ "Systemd FAQ")
* [cron (Русский)](/index.php/Cron_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9) "Cron (Русский)")
**Состояние перевода:** На этой странице представлен перевод статьи [Systemd/Timers](/index.php/Systemd/Timers "Systemd/Timers"). Дата последней синхронизации: 9 февраля 2018\. Вы можете [помочь](/index.php/ArchWiki_Translation_Team_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9) "ArchWiki Translation Team (Русский)") синхронизировать перевод, если в английской версии произошли [изменения](https://wiki.archlinux.org/index.php?title=Systemd/Timers&diff=0&oldid=523878).
Таймеры - файлы служб [systemd](/index.php/Systemd_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9) "Systemd (Русский)"), имя которых оканчивается на `.service`, а также они контролируют файлы `.service` или события. И могут выступать альтернативой [cron](/index.php/Cron_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9) "Cron (Русский)") (смотрите [#В качестве замены cron](#.D0.92_.D0.BA.D0.B0.D1.87.D0.B5.D1.81.D1.82.D0.B2.D0.B5_.D0.B7.D0.B0.D0.BC.D0.B5.D0.BD.D1.8B_cron)). Помимо этого имеют встроенную поддержку событий календаря, монотонных временных событий и могут быть запущены в асинхронном режиме.
## Contents
* [1 Юниты таймера](#.D0.AE.D0.BD.D0.B8.D1.82.D1.8B_.D1.82.D0.B0.D0.B9.D0.BC.D0.B5.D1.80.D0.B0)
* [2 Служба юнита](#.D0.A1.D0.BB.D1.83.D0.B6.D0.B1.D0.B0_.D1.8E.D0.BD.D0.B8.D1.82.D0.B0)
* [3 Управление](#.D0.A3.D0.BF.D1.80.D0.B0.D0.B2.D0.BB.D0.B5.D0.BD.D0.B8.D0.B5)
* [4 Примеры](#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B)
* [4.1 Монотонный таймер](#.D0.9C.D0.BE.D0.BD.D0.BE.D1.82.D0.BE.D0.BD.D0.BD.D1.8B.D0.B9_.D1.82.D0.B0.D0.B9.D0.BC.D0.B5.D1.80)
* [4.2 Таймер в реальном времени](#.D0.A2.D0.B0.D0.B9.D0.BC.D0.B5.D1.80_.D0.B2_.D1.80.D0.B5.D0.B0.D0.BB.D1.8C.D0.BD.D0.BE.D0.BC_.D0.B2.D1.80.D0.B5.D0.BC.D0.B5.D0.BD.D0.B8)
* [5 Временные юниты .timer](#.D0.92.D1.80.D0.B5.D0.BC.D0.B5.D0.BD.D0.BD.D1.8B.D0.B5_.D1.8E.D0.BD.D0.B8.D1.82.D1.8B_.timer)
* [6 В качестве замены cron](#.D0.92_.D0.BA.D0.B0.D1.87.D0.B5.D1.81.D1.82.D0.B2.D0.B5_.D0.B7.D0.B0.D0.BC.D0.B5.D0.BD.D1.8B_cron)
* [6.1 Преимущества](#.D0.9F.D1.80.D0.B5.D0.B8.D0.BC.D1.83.D1.89.D0.B5.D1.81.D1.82.D0.B2.D0.B0)
* [6.2 Предостережения](#.D0.9F.D1.80.D0.B5.D0.B4.D0.BE.D1.81.D1.82.D0.B5.D1.80.D0.B5.D0.B6.D0.B5.D0.BD.D0.B8.D1.8F)
* [6.3 MAILTO](#MAILTO)
* [6.4 Использование crontab](#.D0.98.D1.81.D0.BF.D0.BE.D0.BB.D1.8C.D0.B7.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_crontab)
* [7 Смотрите также](#.D0.A1.D0.BC.D0.BE.D1.82.D1.80.D0.B8.D1.82.D0.B5_.D1.82.D0.B0.D0.BA.D0.B6.D0.B5)
## Юниты таймера
Таймеры *systemd* - это файлы юнитов с суффиксом `.timer`. Они, как и другие [файлы настроек юнитов](/index.php/Systemd_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9)#.D0.9D.D0.B0.D0.BF.D0.B8.D1.81.D0.B0.D0.BD.D0.B8.D0.B5_.D1.84.D0.B0.D0.B9.D0.BB.D0.BE.D0.B2_.D1.8E.D0.BD.D0.B8.D1.82.D0.BE.D0.B2 "Systemd (Русский)"), загружаются по одному и тому же пути, но включают в себя раздел `[Timer]`. Он определяет, как и когда таймер запускается. Существует два типа таймеров:
* **Таймеры реального времени** (также известный как настенные часы) запускаются в зависимости от событий календаря (как cronjobs). Для определения таких таймеров используется опция `OnCalendar=`.
* **Монотонные таймеры** активируются после определенного промежутка времени по отношению к той или иной отправной точки. Они не сработают, если компьютер находится в режиме ожидания или выключен. Есть несколько различных монотонных таймеров, но все они имеют вид: `On*Type*Sec=`. Обычно монотонные таймеры включают в себя `OnBootSec` и `OnActiveSec`.
Для полного объяснения опций таймера смотрите [systemd.timer(5)](https://jlk.fjfi.cvut.cz/arch/manpages/man/systemd.timer.5). Синтаксис аргументов для событий календаря и промежутка времени смотрите в [systemd.time(7)](https://jlk.fjfi.cvut.cz/arch/manpages/man/systemd.time.7).
## Служба юнита
Каждому файлу `.timer` подходит соответствующий файл `.service` (например, `foo.timer` и `foo.service`). `.timer` запускается и контролирует `.service`. `.service` не требует раздела `[Install]`, так как он присутствует в юните *timer*, который уже включен. Если необходимо, то можно контролировать юниты с разным названием, используя опцию `Unit=` в таймере в разделе `[Timer]`.
## Управление
Для того, чтобы использовать юнит *timer*, [включите](/index.php/%D0%92%D0%BA%D0%BB%D1%8E%D1%87%D0%B8%D1%82%D0%B5 "Включите") и [запустите](/index.php/%D0%97%D0%B0%D0%BF%D1%83%D1%81%D1%82%D0%B8%D1%82%D0%B5 "Запустите") его, как любой другой юнит. (не забудьте добавить суффикс `.timer`). Для того, чтобы увидеть все запущенные таймеры, используйте:
`$ systemctl list-timers`
```
NEXT LEFT LAST PASSED UNIT ACTIVATES
Thu 2014-07-10 19:37:03 CEST 11h left Wed 2014-07-09 19:37:03 CEST 12h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Fri 2014-07-11 00:00:00 CEST 15h left Thu 2014-07-10 00:00:13 CEST 8h ago logrotate.timer logrotate.service
```
**Примечание:**
* Чтобы увидеть все таймеры (в том числе и неактивные), используйте `systemctl list-timers --all`.
* Статус сервиса, который запускается посредством таймера, вероятно, будет неактивным, если не сработает условие его запуска.
* Если таймер рассинхронизировался, то может помочь удаление соответствующих файлов `stamp-*` в `/var/lib/systemd/timers` (или `~/.local/share/systemd/`). Эти файлы, с нулевой длинной, которые отмечают последнее время, когда таймер был запущен. Если данные файлы отсутствуют, то они будут перестроены при следующем запуске соответствующего таймера.
## Примеры
Юнит службы может быть запланирован с таймером. В следующем примере назначим запуск `foo.service` в соответствии с таймером `foo.timer`.
### Монотонный таймер
Таймер, который запустится через 15 минут после загрузки, а затем снова будет запускаться каждую неделю во время работы системы.
`/etc/systemd/system/foo.timer`
```
[Unit]
Description=Run foo weekly and on boot
[Timer]
OnBootSec=15min
OnUnitActiveSec=1w
[Install]
WantedBy=timers.target
```
### Таймер в реальном времени
Таймер, который будет запускаться один раз в неделю (в 12:00 в понедельник). При активации он сразу же запустит службу, если отсутствует последнее время запуска (опция `Persistent=true`), например, в связи с отключением системы:
`/etc/systemd/system/foo.timer`
```
[Unit]
Description=Run foo weekly
[Timer]
OnCalendar=weekly
Persistent=true
[Install]
WantedBy=timers.target
```
Если требуется указать более точную дату и время, используйте следующий формат:
```
ДеньНедели Год-Месяц-День Часы:Минуты:Секунды
```
Звездочка может быть использована, чтобы указать все значения, а запятые, в свою очередь, для перечисления возможных значений. Используйте `..`, чтобы выделить какой-то конкретный промежуток. В следующем примере служба запускается в первые четыре дня каждого месяца в полдень, но *только* если день является понедельником или вторником.
```
OnCalendar=Mon,Tue *-*-01..04 12:00:00
```
Запуск службы в первую субботу каждого месяца:
```
OnCalendar=Sat *-*-1..7 18:00:00
```
По крайней мере один день должен быть указан при использовании `ДеньНедели`. Таймер, который будет запускаться каждый день в 4 утра:
```
OnCalendar=*-*-* 4:00:00
```
Более подробная информация доступна в [systemd.time(7)](https://jlk.fjfi.cvut.cz/arch/manpages/man/systemd.time.7).
**Совет:**
* Указатели времени `OnCalendar` могут быть протестированы для того, чтобы проверить их правильность и вычислить следующее время срабатывания условия. Например, `systemd-analyze calendar weekly` или `systemd-analyze calendar "Mon,Tue *-*-01..04 12:00:00"`.
* Специальные выражения событий, такие как `daily` и `weekly`, относятся к *конкретному времени начала* и, таким образом, все таймеры, использующие эти выражения, запустятся одновременно. Таймеры, использующие специальные выражения, могут негативно сказаться на производительности системы, если сервисы, запускаемые таймерами, являются ресурсозатратными. Опция `RandomizedDelaySec` в разделе `[Timer]`помогает избежать подобных проблем посредством случайного выбора времени запуска каждого из таймеров. Смотрите [systemd.timer(5)](https://jlk.fjfi.cvut.cz/arch/manpages/man/systemd.timer.5).
## Временные юниты .timer
Можно использовать `systemd-run` для создания временных юнитов `.timer`. То есть, можно назначить запуск определенной команды в нужно время, не имя файла сервиса. Например, следующая команда создаст файл через 30 секунд:
```
# systemd-run --on-active=30 /bin/touch /tmp/foo
```
Кроме того, можно указать предварительно существующий файл сервиса, при этом не имея файла таймера. Например, запустим юнит, который называется `*некоторыйюнит*.service`, через 12.5 часов:
```
# systemd-run --on-active="12h 30m" --unit *некоторыйюнит*.service
```
Смотрите [systemd-run(1)](https://jlk.fjfi.cvut.cz/arch/manpages/man/systemd-run.1) для получения дополнительной информации и примеров.
## В качестве замены cron
Не смотря на то, что [cron](/index.php/Cron_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9) "Cron (Русский)"), возможно, самый известный планировщик задач, таймеры *systemd* могут выступать в качестве альтернативы.
### Преимущества
Основные преимущества использования таймеров приходят от каждой задачи, которая имеет собственную службу *systemd*. Вот некоторые из этих преимуществ:
* Задачи могут быть легко запущены независимо от их таймеров. Это упрощает отладку.
* Каждая задача может быть настроена для работы в определенной среде (смотрите [systemd.exec(5)](https://jlk.fjfi.cvut.cz/arch/manpages/man/systemd.exec.5)).
* Задачи могут быть присоединены к [cgroups](/index.php/Cgroups "Cgroups").
* Задачи могут быть настроены в зависимости от других юнитов *systemd*.
* Задачи регистрируются в журнале *systemd* для легкости отладки.
### Предостережения
Некоторые вещи, которые легко сделать посредством cron, трудно сделать только юнитами таймера.
* Создание: чтобы настроить задачу, запускаемую в определенное время, при помощи *systemd*, вам нужно создать два файла и использовать команды `systemctl`. Сравните это с добавлением одной строчки в crontab.
* Электронная почта: отсутствие встроенного эквивалента cron `MAILTO` для отправки писем при сбое. В следующем разделе приведен пример создания эквивалента с использованием `OnFailure=`.
### MAILTO
Вы можете настроить systemd для отправки электронной почты при сбое юнита - так же, как Cron делает с `MAILTO`. Прежде всего, нужно два файла: исполняемый для посылки почты и *.service* для запуска первого. В следующем примере, исполняемый файл - скрипт, использующий `sendmail`:
`/usr/local/bin/systemd-email`
```
#!/bin/bash
/usr/bin/sendmail -t <<ERRMAIL
To: $1
From: systemd <root@$HOSTNAME>
Subject: $2
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=UTF-8
$(systemctl status --full "$2")
ERRMAIL
```
В независимости от используемого выполняемого файла, вероятно, следует считывать по крайней мере два аргумента, как делает скрипт: адрес для отправки и файл юнита, чтобы получить его статус. Файл *.service*, который мы создадим, будет передавать следующие аргументы:
`/etc/systemd/system/status-email-*user*@.service`
```
[Unit]
Description=status email for %i to *user*
[Service]
Type=oneshot
ExecStart=/usr/local/bin/systemd-email *address* %i
User=nobody
Group=systemd-journal
```
Где `*user*` - получатель почты, а `*address*` - адрес электронной почты пользователя. Однако получателя изменить нельзя, потому что файл юнита передается как instance-параметр, то есть он может быть использован для отправки почты для других юнитов. Можете [запустить](/index.php/%D0%97%D0%B0%D0%BF%D1%83%D1%81%D1%82%D0%B8%D1%82%D1%8C "Запустить") `status-email-*user*@dbus.service`, чтобы убедиться в том, что вы можете получать почту.
Затем просто [отредактируйте](/index.php/Systemd_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9)#.D0.A0.D0.B5.D0.B4.D0.B0.D0.BA.D1.82.D0.B8.D1.80.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_.D0.BF.D1.80.D0.B5.D0.B4.D0.BE.D1.81.D1.82.D0.B0.D0.B2.D0.BB.D0.B5.D0.BD.D0.BD.D1.8B.D1.85_.D0.BF.D0.B0.D0.BA.D0.B5.D1.82.D0.B0.D0.BC.D0.B8_.D1.84.D0.B0.D0.B9.D0.BB.D0.BE.D0.B2_.D1.8E.D0.BD.D0.B8.D1.82.D0.BE.D0.B2 "Systemd (Русский)") службу, о которой вы хотите получать почту и добавьте `OnFailure=status-email-*user*@%n.service` в раздел `[Unit]`. `%n` передает имя юнита в шаблон.
**Примечание:**
* Если вы настроили SSMTP в соответствии с [SSMTP#Security](/index.php/SSMTP#Security "SSMTP"), то пользователь `nobody` не будет иметь доступа к `/etc/ssmtp/ssmtp.conf` и команда `systemctl start status-email-*user*@dbus.service` не сработает. Одним из решений является использование `root`, как Пользователь, в юните `status-email-*user*@.service`.
* Если вы попробуете использовать `mail -s somelogs *address*` в почтовом скрипте, `mail` создаст свой форк и systemd убьет процесс посылки почты, когда увидит, что скрипт завершился. Можно сделать так, чтобы почтовый процесс не создавал своих форков путем выполнения `mail -Ssendwait -s somelogs *address*`.
### Использование crontab
Некоторые из предостережений можно обойти путем установки пакета, который анализирует crontab, а затем настраивает таймеры на его основе. [systemd-cron-next](https://aur.archlinux.org/packages/systemd-cron-next/) и [systemd-cron](https://aur.archlinux.org/packages/systemd-cron/) - два таких пакета. Они могут предоставлять недостающую функцию `MAILTO`.
Если вам нравится crontabs только потому, что он предоставляет единый вид для всех запланированных задач, `systemctl` делает тоже самое. Смотрите [#Управление](#.D0.A3.D0.BF.D1.80.D0.B0.D0.B2.D0.BB.D0.B5.D0.BD.D0.B8.D0.B5)
## Смотрите также
* [systemd.timer(5)](https://jlk.fjfi.cvut.cz/arch/manpages/man/systemd.timer.5)
* [Fedora Project wiki page](https://fedoraproject.org/wiki/Features/SystemdCalendarTimers) в *systemd* calendar timers (Англ.)
* [Раздел Gentoo wiki](https://wiki.gentoo.org/wiki/Systemd/ru#.D0.A1.D0.B5.D1.80.D0.B2.D0.B8.D1.81.D1.8B_.D1.82.D0.B0.D0.B9.D0.BC.D0.B5.D1.80.D0.BE.D0.B2) Сервисы таймеров *systemd*
* **systemd-cron-next** — утилита для создания таймеров/служб из файлов crontab и anacrontab
[https://github.com/kstep/systemd-cron-next](https://github.com/kstep/systemd-cron-next) || [systemd-cron-next](https://aur.archlinux.org/packages/systemd-cron-next/)
* **systemd-cron** — предоставляет юнитам systemd запускать скрипты cron; используя *systemd-crontab-generator* для конвертации crontab'ов
[https://github.com/systemd-cron/systemd-cron](https://github.com/systemd-cron/systemd-cron) || [systemd-cron](https://aur.archlinux.org/packages/systemd-cron/)