systemd/Timers (简体中文) - ArchWiki

# systemd/Timers (简体中文)

Related articles

- systemd_(简体中文)
- systemd/User
- systemd/Services
- systemd FAQ_(简体中文)
- cron_(简体中文)

翻译状态： 本文是英文页面 Systemd/Timers 的翻译，最后翻译时间：2014-10-25，点击这里可以查看翻译后英文页面的改动。

Timers 是以 `.timer` 为后缀名的 systemd 单元文件，用于控制 `.service` 文件或事件。Timers 可用来替换 cron（阅读 #替换 cron）。Timers 内置了日历定时事件和单调定时事件的支持，并可以异步执行这些事件。

## 定时器单元

Timers 是以 `.timer` 为后缀的 systemd 单元文件。Timers 和其他 单元配置文件 是类似的，它通过相同的路径加载，不同的是包含了 `[Timer]` 部分。 `[Timer]` 部分定义了何时以及如何激活定时事件。Timers 可以被定义成以下两种类型：

- 单调定时器 即从一个时间点过一段时间后激活定时任务。所有的单调计时器都遵循如下形式： `OnTypeSec=`。 `OnBootSec` 和 `OnActiveSec` 是常用的单调定时器。
- 实时定时器 (亦称"挂钟定时器") 通过日历事件激活（类似于 cronjobs ）定时任务。 使用 `OnCalender=` 来定义实时定时器。

要查阅完整的定时器选项，参见 `systemd.timer(5)` man page。 关于日历事件和时间段的定义参见 `systemd.time(7)` man page.

## 服务单元

每个 `.timer` 文件所在目录都得有一个对应的 `.service` 文件（如 `foo.timer` 和 `foo.service`）。`.timer` 用于激活并控制 `.service` 文件。 `.service` 文件中不需要包含 `[Install]` 部分，因为这由 timer 单元接管。必要时通过在定时器的 `[Timer]` 部分指定 `Unit=` 选项来控制一个与定时器不同名的服务单元。

## 管理

使用 timer 单元时像其他单元一样 enable 或 start 即可（别忘了添加 `.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

注意:

- 一个由定时器启动的服务的状态看上去会是 inactive 的，除非它当前正被触发。
- 若一个定时器不再同步，它可能会删除它在 `/var/lib/systemd/timers` 下的 `stamp-*` 文件。这些空文件只用于表示每个定时器上次运行的时间。删除后，他们将在下次定时器运行时自动重建。

## 示例

通过定时器预定执行的服务文件一般无需任何修改。以下示例将预定执行 `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

### 实时定时器

定义一个每周执行一次（明确时间为周一上午十二点）且上次未执行就立即执行的定时器。

    /etc/systemd/system/foo.timer

    [Unit]
    Description=Run foo weekly

    [Timer]
    OnCalendar=weekly
    Persistent=true

    [Install]
    WantedBy=timers.target

提示: 特殊的事件表达式如 `daily` 和 `weekly` 表示 特定的启动时间，因此任何共享该日历事件的定时器将同时启动。如果该定时器的服务会计算系统资源，那么定时器共享启动事件可能会引起系统性能下降。可以考虑手动错开该定时器运行特定事件的时间，如 `OnCalendar=Wed, 23:15`。参见 #注意事项.

## 替换 cron

尽管 cron 毋庸置疑是最有名的计划任务管理器， 但 systemd 定时器仍可以作为一个替代品。

### 优势

使用定时器的最主要的优势在于每个任务都有它自己的 systemd 服务。这样做的好处包括：

- 任务可以简单地独立于他们的定时器启动，简化调试。
- 每个任务可配置运行于特定的环境中（参见 `systemd.exec(5)` man page）。
- 任务可以使用 cgroups 特性。
- 任务可以配置依赖于其他 systemd 单元。
- 任务记录于 systemd 日志，便于调试。

### 注意事项

- 附注：使用 systemd 配置计划任务相比于在 crontab 中只需添加一行任务来说，你需要创建两个文件并运行几次 `systemctl` 命令。 systemd-crontab-generator 和 systemd-cron 可以帮助你使用 crontab 来管理定时器服务。如果你喜欢 crontabs 只是因为它提供了查看所有计划任务的统一视图，`systemctl` 同样可以。参见 #管理。
- 邮件：目前还没有内置与 cron `MAILTO` 类似的任务失败时发送邮件的功能。 可以在每个服务文件中配置 `OnFailure=` 实现同样的功能。
- 随机延时：目前没还有内置与 cron 类似的 `RANDOM_DELAY` 功能来指定一个数字用于定时器延时执行。（参见 bug report）。 你不想同时执行的服务必须手动设置它们的定时器。

  注意: `AccuracySec` 选项对于随机错开定时器执行时间是 没有 作用的，因为它"会在所有本地定时器单元间同步" (`systemd.timer(5)`)。换句话说， `AccuracySec` 会以相同的量改变所有定时器激活时间。例如，所有 `OnCalendar=daily` 的定时器单元，指定 `AccuracySec=15m` 将同时在 00:00 到 00:15 触发相关的服务。

## 参见

- systemd.timer man page on freedesktop.org
- Fedora Project wiki page on systemd calendar timers
- Gentoo wiki section on systemd timer services
- systemd-crontab-generator — 一个从 crontab 和 anacrontab 文件生成 timers/services 文件的工具

  https://github.com/kstep/systemd-crontab-generator || systemd-crontab-generator

- systemd-cron — 提供 systemd 单元运行 cron 脚本；使用 systemd-crontab-generator 转换 crontabs

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

Categories:

- Daemons and system services (简体中文)
- Boot process (简体中文)