Jump to content

Systemd/timers/zh: Difference between revisions

From NixOS Wiki
Ardenet (talk | contribs)
Created page with "定时器是 systemd 中名称以 .timer 结尾的单元文件,用于控制 .service 文件或事件。定时器可以用作 <code>cron</code> 的替代方案。定时器内置对基于日历的事件和普通时间事件的支持,并且可以异步运行。"
Ardenet (talk | contribs)
Created page with "== 配置 =="
 
(One intermediate revision by the same user not shown)
Line 4: Line 4:
<span id="Configuration"></span>
<span id="Configuration"></span>
== 配置 ==
== 配置 ==
<div lang="en" dir="ltr" class="mw-content-ltr">
以下示例定时器每 5 分钟运行一次 systemd 单元以调用 bash 脚本。
The following example timer runs a systemd unit every 5 minutes which invokes a bash script.
</div>
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
systemd.timers."hello-world" = {
systemd.timers."hello-world" = {
Line 92: Line 90:
====Running timer on a schedule====
====Running timer on a schedule====


<div lang="en" dir="ltr" class="mw-content-ltr">
以下示例每天启动一次(凌晨 12:00)。激活后,例如如果由于系统关闭错过了上次启动时间(同时设置选项 Persistent=true),,则会立即触发服务。
The following example starts once a day (at 12:00am). When activated, it triggers the service immediately if it missed the last start time (option Persistent=true), for example due to the system being powered off.
</div>
<syntaxHighlight lang="nix">
<syntaxHighlight lang="nix">
...
...
Line 103: Line 99:
};
};
</syntaxHighlight>
</syntaxHighlight>
<div lang="en" dir="ltr" class="mw-content-ltr">
更多示例可以在 [https://wiki.archlinux.org/title/Systemd/Timers Arch Wiki] <code>systemd.timer</code> 手册页中找到。
More examples can be found at the [https://wiki.archlinux.org/title/Systemd/Timers Arch Wiki] and at the <code>systemd.timer</code> manpage.
</div>
<span id="Usage"></span>
<span id="Usage"></span>
== 用法 ==
== 用法 ==
<div lang="en" dir="ltr" class="mw-content-ltr">
列出活跃定时器及其当前状态:
List active timers and their current state:
</div>
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
systemctl list-timers
systemctl list-timers
</syntaxhighlight>
</syntaxhighlight>
<div lang="en" dir="ltr" class="mw-content-ltr">
为了测试目的,手动运行一次服务:
Manually run a service once for testing purposes:
</div>
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
systemctl start hello-world
systemctl start hello-world
</syntaxhighlight>
</syntaxhighlight>
[[Category:systemd]]
[[Category:systemd]]

Latest revision as of 12:06, 8 October 2025

定时器是 systemd 中名称以 .timer 结尾的单元文件,用于控制 .service 文件或事件。定时器可以用作 cron 的替代方案。定时器内置对基于日历的事件和普通时间事件的支持,并且可以异步运行。

配置

以下示例定时器每 5 分钟运行一次 systemd 单元以调用 bash 脚本。

systemd.timers."hello-world" = {
  wantedBy = [ "timers.target" ];
    timerConfig = {
      OnBootSec = "5m";
      OnUnitActiveSec = "5m";
      # Alternatively, if you prefer to specify an exact timestamp
      # like one does in cron, you can use the `OnCalendar` option
      # to specify a calendar event expression.
      # Run every Monday at 10:00 AM in the Asia/Kolkata timezone.
      #OnCalendar = "Mon *-*-* 10:00:00 Asia/Kolkata";
      Unit = "hello-world.service";
    };
};

systemd.services."hello-world" = {
  script = ''
    set -eu
    ${pkgs.coreutils}/bin/echo "Hello World"
  '';
  serviceConfig = {
    Type = "oneshot";
    User = "root";
    RemainAfterExit = true; # Prevents the service from automatically starting on rebuild. See https://discourse.nixos.org/t/how-to-prevent-custom-systemd-service-from-restarting-on-nixos-rebuild-switch/43431
  };
};


Alternatively here, avoid quotes when calling for the binary and its command options:

${pkgs.foo}/bin/foo command-options

This will yield the same result as running

foo command-options

in your terminal.

Verifying your timestamp for systemd.time

If you do not understand the format that systemd.time expects, you can use the systemd-analyze's calendar sub-command to understand the next N times when the timer will get triggered. Following is an example:

$ systemd-analyze calendar --iterations=5 "10:00:00"
  Original form: 10:00:00
Normalized form: *-*-* 10:00:00
    Next elapse: Sat 2024-12-07 10:00:00 IST
       (in UTC): Sat 2024-12-07 04:30:00 UTC
       From now: 33min left
   Iteration #2: Sun 2024-12-08 10:00:00 IST
       (in UTC): Sun 2024-12-08 04:30:00 UTC
       From now: 24h left
   Iteration #3: Mon 2024-12-09 10:00:00 IST
       (in UTC): Mon 2024-12-09 04:30:00 UTC
       From now: 2 days left
   Iteration #4: Tue 2024-12-10 10:00:00 IST
       (in UTC): Tue 2024-12-10 04:30:00 UTC
       From now: 3 days left
   Iteration #5: Wed 2024-12-11 10:00:00 IST
       (in UTC): Wed 2024-12-11 04:30:00 UTC
       From now: 4 days left

Using the systemd.services.<name>.startAt shorthand

If you only want a service to execute at an interval and don't plan to configure the timer much more, you can use the systemd.services.<name>.startAt option. This will have the underlying systemd module in nixpkgs create the timer for you, and set its OnCalendar field. Note that the semantics for OnCalendar are different to OnUnitActiveSec.

This example shows the previous hello-world service configured with startAt, running every 5 minutes.

systemd.services."hello-world" = {
  script = ''
    set -eu
    ${pkgs.coreutils}/bin/echo "Hello World"
  '';
  serviceConfig = {
    Type = "oneshot";
    User = "root";
  };
  startAt = "*:0/5";
};

Running timer on a schedule

以下示例每天启动一次(凌晨 12:00)。激活后,例如如果由于系统关闭错过了上次启动时间(同时设置选项 Persistent=true),,则会立即触发服务。

...
  timerConfig = {
      OnCalendar = "daily";
      Persistent = true; 
  };
};

更多示例可以在 Arch Wikisystemd.timer 手册页中找到。

用法

列出活跃定时器及其当前状态:

systemctl list-timers

为了测试目的,手动运行一次服务:

systemctl start hello-world