# systemd/Timers (Русский)

< Systemd

Related articles

- systemd (Русский)
- systemd/Пользователь
- systemd FAQ
- cron (Русский)

Состояние перевода: На этой странице представлен перевод статьи Systemd/Timers. Дата последней синхронизации: 10 октября. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Таймеры - файлы служб systemd, имя которых оканчивается на `.service`, а также они контролируют файлы `.service` или события. И могут выступать альтернативой cron (смотрите #В качестве замены cron). Помимо этого имеют встроенную поддержку событий календаря, монотонных временных событий и могут быть запущены в асинхронном режиме.

## Юниты таймера

Таймеры systemd - это файлы юнитов с суффиксом `.timer`. Они, как и другие файлы настроек юнитов, загружаются по одному и тому же пути, но включают в себя раздел `[Timer]`. Он определяет, как и когда таймер запускается. Таймер может быть одним из следующих двух типов:

- Монотонный таймер - активируется после определенного промежутка времени по отношению к той или иной отправной точки. Есть несколько различных монотонных таймеров, но все они имеют вид: `OnTypeSec=`. `OnBootSec` и `OnActiveSec` являются общими монотонными таймерами.
- Таймер реального времени (также известный как таймер настенный часы) - запускается в зависимости от событий календаря (как cronjobs). Для определения такого таймера используется опция `OnCalendar=`.

Для полного объяснения опций таймера смотрите systemd.timer(5). Синтаксис аргументов для событий календаря и промежутка времени смотрите в systemd.time(7).

## Служба юнита

Каждому файлу `.timer` подходит соответствующий файл `.service` (например, `foo.timer` и `foo.service`). `.timer` запускается и контролирует `.service`. `.service` не требует раздела `[Install]`, так как он присутствует в юните timer, который уже включен. Если необходимо, то можно контролировать юниты с разным названием, используя опцию `Unit=` в таймере в разделе `[Timer]`.

## Управление

Для того, чтобы использовать юнит timer, включите и запустите его, как любой другой юнит. (не забудьте добавить суффикс `.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`. Эти файлы, с нулевой длинной, которые отмечают последнее время, когда таймер был запущен. Если данные файлы отсутствуют, то они будут перестроены при следующем запуске соответствующего таймера.

## Пример

Не требуется никаких изменений в файлах юнита службы, чтобы использовать его вместе с таймером. В следующем примере назначим запуск `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

Если требуется указать более точную дату и время, используйте следующий формат: `ДеньНедели Год-Месяц-День Часы:Минуты:Секунды`. Звездочка может быть использована, чтобы указать все значения, а запятые, в свою очередь, для перечисления возможных значений. Используйте `..`, чтобы выделить какой-то конкретный промежуток. В следующем примере сервис запускается в первые четыре дня каждого месяца в полдень, но только, если этими днями являются понедельник или вторник. Более подробная информация доступна в systemd.time(7).

    OnCalendar=Mon,Tue *-*-01..04 12:00:00

Совет: Специальные выражения событий, такие как `daily` и `weekly`, относятся к конкретному времени начала и, таким образом, все таймеры, использующие эти выражения, запустятся одновременно. Таймеры, использующие специальные выражения, могут негативно сказаться на производительности системы, если сервисы, запускаемые таймерами, являются ресурсозатратными. Опция `RandomizedDelaySec` помогает избежать подобных проблем посредством случайного выбора времени запуска каждого из таймеров. Смотрите 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) для получения дополнительной информации и примеров.

## В качестве замены cron

Не смотря на то, что cron, возможно, самый известный планировщик задач, таймеры systemd могут выступать в качестве альтернативы.

### Преимущества

Основные преимущества использования таймеров приходят от каждой задачи, которая имеет собственную службу systemd. Вот некоторые из этих преимуществ:

- Задачи могут быть легко запущены независимо от их таймеров. Это упрощает отладку.
- Каждая задача может быть настроена для работы в определенной среде (смотрите systemd.exec(5)).
- Задачи могут быть присоединены к 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-параметр, то есть он может быть использован для отправки почты для других юнитов. Можете запустить `status-email-user@dbus.service`, чтобы убедиться в том, что вы можете получать почту.

Затем просто отредактируйте службу, о которой вы хотите получать почту и добавьте `OnFailure=status-email-user@%n.service` в раздел `[Unit]`. `%n` передает имя юнита в шаблон.

Примечание:

- Если вы настроили SSMTP в соответствии с SSMTP#Security, то пользователь `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-nextAUR и systemd-cronAUR - два таких пакета. Они могут предоставлять недостающую функцию `MAILTO`.

Если вам нравится crontabs только потому, что он предоставляет единый вид для всех запланированных задач, `systemctl` делает тоже самое. Смотрите #Управление

## Смотрите также

- systemd.timer(5)
- Fedora Project wiki page на systemd calendar timers (Англ.)
- Раздел Gentoo wiki Сервисы таймеров systemd
- systemd-cron-next — утилита для создания таймеров/служб из файлов crontab и anacrontab

  https://github.com/kstep/systemd-cron-next || systemd-cron-nextAUR

- systemd-cron — предоставляет юнитам systemd запускать скрипты cron; используя systemd-crontab-generator для конвертации crontab'ов

  https://github.com/systemd-cron/systemd-cron || systemd-cronAUR

Categories:

- Русский
- Daemons and system services (Русский)
- Boot process (Русский)