跳到内容跳到页面导航:上一页 [access key p]/下一页 [access key n]
documentation.suse.com / 使用 systemd 计时器

使用 systemd 计时器

出版日期:2024-11-12
解释

从定期运行备份脚本,到计算机引导后立即启动特定进程,Linux 系统上有大量的任务需要调度。systemd 计时器提供了一个灵活的机制用于调度及管理作业和服务。

原因

本文旨在提供 systemd 计时器的完整概述,涵盖创建、维护、测试、查错以及从 cron 迁移等方面的信息。

工作量

创建示例 systemd 计时器需要 10 分钟。最多花费 30 分钟即可完全了解 systemd 计时器的工作原理。

要求

1 systemd 计时器概念

systemd 计时器单元提供一个用于在 Linux 上调度作业的机制。这些作业的执行时间可以基于时间和日期或基于事件。

systemd 计时器单元通过 .timer 文件扩展名标识。每个计时器文件都需要一个由它控制的相应服务文件。也就是说,计时器文件将激活并管理相应的服务文件。systemd 计时器支持以下功能:

  • 使用计时器单元安排的作业可以依赖其他 systemd 服务。计时器单元被视为常规 systemd 服务,因此可以使用 systemctl 进行管理。

  • 计时器可以是实时的(基于日历事件触发),也可以是单调性的(自特定起始时刻经过指定的时间后触发)。

  • 时间单元将记录到系统日记中,这样用户便能更轻松地对时间单元进行监控和查错。

  • 计时器使用集中式 systemd 管理服务。

  • 如果系统在预期执行期间关闭,则一旦系统再次运行,就会执行计时器。

2 创建计时器

以下示例说明如何设置下面这样的计时器:在引导后触发 helloworld.sh 外壳脚本,并相对于其激活时间每隔 24 小时重复执行一次。此外,计时器会在星期一至星期五上午 10 点运行。

2.1 Hello World 示例

  1. 创建包含以下内容的 /etc/systemd/system/helloworld.service 文件:

    [Unit]
    Description="Hello World script"
    
    [Service]
    ExecStart=/usr/local/bin/helloworld.sh

    这是一个 systemd 服务文件,告知 systemd 要运行哪个应用程序。

  2. 创建包含以下内容的 /etc/systemd/system/helloworld.timer 文件:

    [Unit]
    Description="Run helloworld.service 5min after boot and every 24 hours relative to activation time"
    
    [Timer]
    OnBootSec=5min
    OnUnitActiveSec=24h
    OnCalendar=Mon..Fri *-*-* 10:00:*
    Unit=helloworld.service
    
    [Install]
    WantedBy=multi-user.target

    这是计时器文件,用于控制相应服务文件的激活。

  3. 校验您先前创建的文件是否不含错误:

    > systemd-analyze verify /etc/systemd/system/helloworld.*

    如果命令未返回任何输出,则表示文件成功通过了校验。

  4. 启动计时器:

    > sudo systemctl start helloworld.timer

    仅针对当前会话激活计时器。

  5. 启用计时器以确保在引导时将其激活:

    > sudo systemctl enable helloworld.timer

2.2 示例解释

例 1︰ 服务文件
[Unit]
Description="Hello World script"1

[Service]
ExecStart=/usr/local/bin/helloworld.sh2

1

解释服务文件用途的简短说明。

2

要执行的应用程序。

要使服务文件能够正常运行,至少需要指定 [Unit][Service] 部分。systemd 服务文件通常包含 [Install] 部分,该部分用于确定要加载的一个或多个服务目标。计时器的服务文件中不需要此部分,因为此信息已在计时器文件中提供。有关高级配置,请参见Managing systemd targets with systemctl

例 2︰ 计时器文件
[Unit]
Description="Run helloworld.service 5min after boot and every 24 hours relative to activation time"1

[Timer]
OnBootSec=5min2
OnUnitActiveSec=24h3
OnCalendar=Mon..Fri *-*-* 10:00:*4
Unit=helloworld.service5

[Install]
WantedBy=multi-user.target6

1

解释计时器文件用途的简短说明。

2

指定一个用于在系统引导 5 分钟后触发服务的计时器。有关详细信息,请参见单调计时器

3

指定一个用于在激活服务 24 小时后触发服务(即每天触发一次)的计时器。有关详细信息,请参见实时计时器

4

指定一个在固定时间点(在本示例中为星期一至星期五上午 10 点)触发服务的计时器。有关详细信息,请参见实时计时器

5

要执行的服务文件。

6

要在其中激活计时器的 systemd 目标。有关 systemd 目标的详细信息,请参见 Managing systemd targets with systemctl

3 管理计时器

可以使用 systemctl 命令管理计时器。

启动和停止计时器
> sudo systemctl start TIMER.timer
> sudo systemctl restart TIMER.timer
> sudo systemctl stop TIMER.timer
启用和禁用计时器
> sudo systemctl enable TIMER.timer
> sudo systemctl disable TIMER.timer
显示计时器文件内容
> sudo systemctl cat TIMER.timer
检查特定的计时器
> sudo systemctl status TIMER.timer
例 3︰ 计时器状态
> sudo systemctl status helloworld.timer
● helloworld.timer - "Run helloworld.service 5min after boot and every 24 hours
relative to activation time"1
Loaded: loaded (/etc/systemd/system/helloworld.timer; disabled; vendor preset: disabled)2
Active: active (waiting) since Tue 2022-10-26 18:35:41 CEST; 6s ago3
Trigger: Wed 2022-10-27 18:35:41 CEST; 23h left4
Triggers: ● helloworld.service5
6
Oct 26 18:35:41 neo systemd[1]: Started "Run helloworld.service 5min after boot and every 24 hours relative to activation time".7

1

计时器的文件名和说明。

2

列出计时器是否已成功分析并保留在内存中(已加载),显示计时器文件的完整路径,以及计时器在系统引导时会启动(已启用)还是不会启动(已禁用)。第一个值显示当前系统配置,第二个值显示供应商预设的值。

3

指示计时器是处于活动状态(正在等待触发事件)还是非活动状态。如果处于活动状态,它还会显示自上次激活以来经过的时间(在本示例中为 6 秒)。

4

下次触发计时器的日期和时间。

5

计时器触发的服务文件的名称。

6

指向文档(例如手册页)的可选行。如果不可用,则显示空行(如本示例中所示)。

7

计时器创建的最新日记项。

要列出系统上所有可用的计时器,请使用 systemctl list-timers。下列选项可用:

列出所有活动计时器:
> sudo systemctl list-timers
列出所有计时器,包括非活动的计时器:
> sudo systemctl list-timers --all
列出与模式匹配的所有计时器:
> sudo systemctl list-timers PATTERN
> sudo systemctl list-timers --allPATTERN

PATTERN 必须是一个名称或外壳通配表达式。可以使用运算符 *?[]。有关通配模式的详细信息,请参见 man 7 glob

列出与特定状态匹配的计时器:
> sudo systemctl list-timers --state=STATE

STATE 接受以下值:activefailedloadsub。有关详细信息,请参见man systemctl

例 4︰ 列出计时器

运行任何 systemctl list-timers 都会生成如下所示的表。此示例列出了与模式 snapper* 匹配的所有活动计时器:

> sudo systemctl list-timers snapper*
NEXT1                       LEFT2      LAST3                        PASSED4   UNIT5                  ACTIVATES6

-----------------------------------------------------------------------------------------------------------------------------
Tue 2022-10-26 19:00:00 CEST 39min left Tue 2022-10-26 18:00:29 CEST 19min ago snapper-timeline.timer snapper-timeline.service
Wed 2022-10-27 08:33:04 CEST 14h   left Tue 2022-10-26 08:33:04 CEST 9h ago    snapper-cleanup.timer  snapper-cleanup.service

1

下次运行计时器的时间点。

2

距离下次运行计时器的剩余时间。

3

上次运行计时器的时间点。

4

自上次运行计时器以来经过的时间。

5

计时器单元的名称。

6

计时器激活的服务的名称。

4 计时器类型

systemd 支持两种类型的计时器:实时(基于日历)和单调(基于事件)。尽管计时器通常是永久性的,但 systemd 还允许设置仅对当前会话有效的瞬态计时器。

实时计时器

实时计时器由日历事件触发。它们是使用选项 OnCalendar 定义的。

您可以基于日期和时间指定何时触发事件。使用以下模板:

OnCalendar=DayOfWeek1 Year-Month-Day2 Hour:Minute:Second3

1

星期日期。可能的值为 SunMonTueWedThuFriSat。留空会忽略星期日期。

2

日期。用两位数指定月和日,用四位数指定年。可以用通配符 * 替换每个值,以匹配每个出现的值。

3

时间。用两位数指定每个值。可以用通配符 * 替换每个值,以匹配每个出现的值。

适用于所有值:用两个点定义连续范围 (Mon..Fri)。用逗号分隔各个不同值的列表 (Mon,Wed,Fri)。

例 5︰ 实时计时器示例
  • 每个星期五的下午 6 点:

    OnCalendar=Fri *-*-* 18:00:00
  • 每天上午 5 点:

    OnCalendar=Mon..Sun *-*-* 5:00:00
  • 星期日和星期二凌晨 1 点和 3 点:

    OnCalendar=Tue,Sun *-*-* 01,03:00:00
  • 单个日期:

    OnCalendar=Mo..Sun 2023-09-23 00:00:01
  • 要指定不同时间的触发器,可以在单个计时器文件中创建多个 OnCalendar 项:

    OnCalendar=Mon..Fri *-*-* 10:00
    OnCalendar=Sat,Sun *-*-* 22:00

有关可用功能和选项的完整列表,请参见 man 7 systemd.time,其中提供了有关以下主题的其他信息:

  • 缩短语法并使用缩写

  • 指定重复次数

  • 查找特定的月份日期(月份的最后一日、最后一个星期日等)

  • 应用时区

单调计时器

单调计时器在发生特定事件(例如系统引导或系统单元激活事件)后经过指定的时间时触发。值按时间单位(分钟、小时、日、月、年等)定义。支持以下单位:usecmsecsecondsminuteshoursdaysweeksmonthsyears。可以使用多个选项来定义单调计时器:

  • OnActiveSec:激活单元后经过的时间

    OnActiveSec=50minutes
  • OnBootSec:系统引导后经过的时间

    OnBootSec=10hours
  • OnStartupSec:启动服务管理器后经过的时间。对于系统服务,此选项大致相当于 OnActiveSec。请将此选项用于相应服务管理器会在用户登录时启动的用户服务。

    OnStartupSec=5minutes 20seconds
  • OnUnitActiveSec:上次激活相应服务后经过的时间

    OnUnitActiveSec=10seconds
  • OnUnitInactiveSec:上次停用相应服务后经过的时间

    OnUnitInactiveSec=2hours 15minutes 18 seconds
瞬态计时器

瞬态计时器是仅对当前会话有效的临时计时器。借助这些计时器,可以使用现有的服务文件或直接启动程序。可以运行 systemd-run 来调用瞬态计时器。

以下示例每隔两小时运行一次 helloworld.service 单元:

> sudo systemd-run --on-active="2hours" --unit="helloworld.service"

要直接运行某个命令,请使用以下语法。此示例直接调用脚本 /usr/local/bin/helloworld.sh

> sudo systemd-run --on-active="2hours" /usr/local/bin/helloworld.sh

如果命令接受参数,请用空格分隔添加的参数:

> sudo systemd-run --on-active="2hours" /usr/local/bin/helloworld.sh --language=pt_BR

瞬态计时器可以是单调的,也可以是实时的。支持以下开关,其工作方式如单调计时器中所述:

  • --on-active

  • --on-startup

  • --on-unit-active

  • --on-unit-inactive

  • --on-calendar

有关详细信息,请参见 man 1 systemd-run

5 测试日历项

systemd 提供了用于为实时计时器测试和创建日历计时器项的工具,即 systemd-analyze calendar。此工具接受的参数与用于设置实时计时器的 OnCalendar 项相同。

您可以串联多个参数(用空格分隔)。如果要测试的字词正确,则输出会显示下次触发计时器的时间(以本地时间和 UTC 表示)。其中还会显示Normalized form的字符串,建议在计时器文件中使用该字符串。考虑下列示例:

> systemd-analyze calendar "Tue,Sun *-*-* 01,03:00:00"
Normalized form: Tue,Sun *-*-* 01,03:00:00
Next elapse: Sun 2021-10-31 01:00:00 CEST
(in UTC): Sat 2021-10-30 23:00:00 UTC
From now: 3 days left

> systemd-analyze calendar "Mon..Fri *-*-* 10:00" "Sat,Sun *-*-* 22:00"
Original form: Mon..Fri *-*-* 10:00
Normalized form: Mon..Fri *-*-* 10:00:00
Next elapse: Thu 2021-10-28 10:00:00 CEST
(in UTC): Thu 2021-10-28 08:00:00 UTC
From now: 19h left

Original form: Sat,Sun *-*-* 22:00
Normalized form: Sat,Sun *-*-* 22:00:00
Next elapse: Sat 2021-10-30 22:00:00 CEST
(in UTC): Sat 2021-10-30 20:00:00 UTC
From now: 3 days left

对于重复性计时器,请使用 –iterations N 开关列出触发时间,然后测试计时器是否按预期工作。参数 N 指定您要测试的迭代次数。以下示例字符串在星期日每隔 8 小时(从 00:00:00 开始)触发一次计时器:

> systemd-analyze calendar --iterations 5 "Sun *-*-* 0/08:00:00"
Original form: Sun *-*-* 0/08:00:00
Normalized form: Sun *-*-* 00/8:00:00
Next elapse: Sun 2021-10-31 00:00:00 CEST
(in UTC): Sat 2021-10-30 22:00:00 UTC
From now: 3 days left
Iter. #2: Sun 2021-10-31 08:00:00 CET
(in UTC): Sun 2021-10-31 07:00:00 UTC
From now: 3 days left
Iter. #3: Sun 2021-10-31 16:00:00 CET
(in UTC): Sun 2021-10-31 15:00:00 UTC
From now: 4 days left
Iter. #4: Sun 2021-11-07 00:00:00 CET
(in UTC): Sat 2021-11-06 23:00:00 UTC
From now: 1 week 3 days left
Iter. #5: Sun 2021-11-07 08:00:00 CET
(in UTC): Sun 2021-11-07 07:00:00 UTC
From now: 1 week 3 days left

6 当计时器失败时接收电子邮件通知

systemd 未提供与 cron 的 MAILTO 类似的功能。以下过程介绍了当计时器失败时启用电子邮件通知的解决方法。

该过程包括以下步骤:

  1. 创建一个用于发送电子邮件的脚本。

  2. 创建运行电子邮件脚本的 systemd 服务文件。

  3. 测试电子邮件服务文件。

  4. 在计时器控制的服务中,通过 OnFailure 调用创建的电子邮件服务文件。

以下示例将使用软件包 mailx 中的 mailx 命令。这需要安装并正确配置 Postfix 电子邮件服务器。

  1. 创建脚本 /usr/local/bin/send_systemd_email

    1. 该脚本需要两个参数:$1(电子邮件地址)和 $2(收到的失败通知所对应服务文件的名称)。这两个参数均由运行邮件脚本的单元文件提供。

      #!/bin/sh
      systemctl status --full "$2" | mailx -S sendwait\
       -s "Service failure for $2" -r root@$HOSTNAME $1
    2. 确保该脚本可执行:

      > sudo chmod 755 /usr/local/bin/send_systemd_email
  2. 创建文件 /etc/systemd/system/send_email_to_USER@.service

    [Unit]
    Description=Send systemd status information by email for %i to USER
    
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/send_systemd_email EMAIL_ADDRESS %i
    User=root
    Group=systemd-journal

    将文件中的 USEREMAIL_ADDRESS 分别替换为要接收电子邮件的用户的登录名和电子邮件地址。%i 是失败的服务的名称(它将通过 %n 参数传递给电子邮件服务)。

  3. 校验服务文件并修复报告的问题:

    > systemd-analyze verify /etc/systemd/system/send_email_to_USER@.service

    如果命令未返回任何输出,则表示文件成功通过了校验。

  4. 要校验整个过程,请使用 dbus 实例启动服务进行测试。(可以使用当前正在运行的任何其他服务。本示例之所以使用 dbus,是因为该服务肯定可以在任何安装的系统上运行。)

    > sudo systemctl start send_email_to_USER@dbus.service

    如果成功,EMAIL_ADDRESS 会收到一封电子邮件,其主题为 Service failure for dbus,正文包含 dbus 状态消息。(这只是一项测试,dbus 服务本身并未出现问题。您可以放心删除该电子邮件,无需执行任何操作)。

    如果测试电子邮件已成功发送,请将其集成到您的服务文件中。

  5. 要向服务添加电子邮件通知,请将 OnFailure 选项添加到在发生失败时用于接收通知的服务文件的 Unit 部分:

    [Unit]
    Description="Hello World script"
    OnFailure1=send_email_to_USER2@%n3.service
    
    [Service]
    ExecStart=/usr/local/bin/helloworld.sh

    1

    OnFailure 选项接受将某个服务作为参数。

    2

    将此服务单元文件名部分替换为登录名。

    3

    指定服务的名称(在本示例中为 helloworld)。此名称在电子邮件服务文件中以 %i 形式提供。

  6. 您已成功为 systemd 服务设置失败通知。

提示
提示:向多个用户发送电子邮件通知

电子邮件服务文件已将收件人的电子邮件地址硬编码。要向其他用户发送通知电子邮件,请复制电子邮件服务文件,并替换文件名中的用户登录名,以及抄送行中的电子邮件地址。

要同时向多个收件人发送失败通知,请将相应的服务文件添加到该服务文件(使用空格作为分隔符):

OnFailure=send_email_to_tux@%n.service send_email_to_wilber@%n.service

7 以普通用户身份使用计时器

普通用户也可以使用 systemd 计时器。这些计时器可帮助您自动完成重复性任务,例如备份、处理图像或将数据移到云中。

适用于系统范围计时器的过程和任务同样适用于 systemd 计时器。但是,两者存在以下差异:

  • 计时器和服务文件必须放在 ~/.config/systemd/user/ 中。

  • 必须结合 --user 开关运行所有 systemctljournalctl 命令。systemd-analyze 需要此选项。

    作为普通用户,您必须提供单元文件的路径,如以下示例中所示。否则,如果存在同名的系统范围计时器,则会执行或列出该系统范围计时器。

    > systemctl --user start ~/.config/systemd/user/helloworld.timer
    > systemctl --user enable ~/.config/systemd/user/helloworld.timer
    > systemctl --user list-timers
    > journalctl --user -u helloworld.*
    > systemd-analyze verify ~/.config/systemd/user/helloworld.timer
重要
重要:用户计时器仅在活动会话期间运行

与以普通用户身份启动的其他 systemd 服务一样,用户计时器仅在用户登录后才运行。要在引导时启动用户计时器并在注销后使其保持运行,请为每个受影响的用户启用存留

sudo loginctl enable-linger USER

有关详细信息,请参见 man 1 loginctl

重要
重要:不继承环境变量

systemd 用户实例不会继承 ~/.profile~/.bashrc 等脚本设置的环境变量。要检查 systemd 环境,请运行 systemctl --user show-environment

要导入 systemd 环境中缺少的任何变量,请在 ~/.bashrc 末尾指定以下命令:

systemctl --user import-environment VARIABLE1 VARIABLE2

8 从 cron 迁移到 systemd 计时器

所有 cron 作业都可以迁移到 systemd 计时器。下面提供了说明和示例。

  1. 创建执行脚本的服务文件。有关详细信息,请参见例 1 “服务文件”

  2. 创建执行服务文件的计时器文件。有关一般说明,请参见例 2 “计时器文件”

    1. 转换日历项。cron 和 systemd 中指定时间的方式不相同。使用以下模式作为转换模板:

      Cron:               Minute Hour Day Month DayOfWeek
      systemd: OnCalendar=DayOfWeek Year-Month-Day Hour:Minute:Second

      要测试转换后的日历项,请按照第 5 节 “测试日历项”中的说明操作。

    2. 转换 cron 别名 (@NICK):

      Cron     : systemd timer
      -------- : ----------------------------
      @reboot  : OnBootSec=1s
      @yearly  : OnCalendar=*-01-01 00:00:00
      @annually: OnCalendar=*-01-01 00:00:00
      @monthly : OnCalendar=*-*-01 00:00:00
      @weekly  : OnCalendar=Sun *-*-* 00:00:00
      @daily   : OnCalendar=*-*-* 00:00:00
      @hourly  : OnCalendar=*-*-* *:00:00
    3. 转换变量赋值。systemd 变量赋值必须在 [Service] 部分中定义。不能以这种方式转换 MAILTO - 具体请参见下一步。

      cron: VARIABLE=VALUE
      systemd: Environment="VARIABLE=VALUE"
    4. 按照第 6 节 “当计时器失败时接收电子邮件通知”中的说明设置电子邮件通知,以替换 cron 的 MAILTO 功能。

例 6︰ 从 cron 迁移到 systemd 计时器

下面是在引导后经过 5 分钟并在每个星期一至星期五 10 点调用脚本 helloworld.sh 的 crontab 项:

@reboot sleep 300 && /usr/local/bin/helloworld.sh
0 10 * * * 1-5 /usr/local/bin/helloworld.sh

调用脚本的 systemd 服务文件 (helloworld.service) 如下所示:

[Unit]
Description="Hello World script"
[Service]
ExecStart=/usr/local/bin/helloworld.sh

计时器文件 (helloworld.timer) 如下所示:

[Unit]
Description="Run helloworld.service 5min after boot and at 10am every Mon-Fri"
[Timer]
OnBootSec=5min
OnCalendar=Mon..Fri *-*-* 10:00:*
Unit=helloworld.service
[Install]
WantedBy=multi-user.target

9 查错和常见问题

了解如何对失败的 systemd 计时器进行调试和查错。查找有关 systemd 计时器的常见问题解答。

9.1 避免错误

为了避免 systemd 计时器出现错误,请确保遵循以下最佳实践:

  • 校验您在服务中使用 ExecStart 指定的可执行文件是否正确运行。

  • 运行 systemd-analyze verify FILE 来检查服务和计时器文件的语法。

  • 运行 systemd-analyze calendar CALENDER_ENTRY 来检查日历项的执行时间。

9.2 事件未触发

当您激活包含非严重错误的计时器时,systemd 将静默忽略这些错误。例如:

例 7︰ 包含非致命错误的 systemd 计时器文件中断
[Timer]
OnBootSec=5min
OnClendar=Mon..Fri 10:00
Unit=helloworld.service

第 3 行包含语法错误(应该是 OnClendar,而不是 OnCalendar)。由于 [Timer] 部分包含另一个计时器项 (OnBoot),因此该错误并不严重,将被静默忽略。因此,星期一至星期五的触发器不会执行。检测错误的唯一方法是使用命令 systemd-analyze verify

#  systemd-analyze verify /etc/systemd/system/helloworld.timer
/etc/systemd/system/helloworld.timer:7: Unknown key name 'OnClendar' in section 'Timer', ignoring.

9.3 在系统日记中检查错误

与每项 systemd 服务一样,计时器触发的事件和操作会记录到系统日记中。如果触发器未按预期运行,请使用 journalctl 检查日志消息。要过滤日记以显示相关信息,请使用 -u 开关指定 systemd 计时器和服务文件。使用此选项可显示计时器相应服务文件的日志项:

sudo journalctl -u  helloworld.timer -u helloworld.service

或使用更短的选项格式(如果适用):

sudo journalctl -u  helloworld.*

journalctl 是支持许多选项和过滤器的工具。请参见 man 1 journalctl 获取深入信息。以下选项对于计时器查错非常有用:

  • -b:仅显示当前引导对应的项。

  • -S today:仅显示当日的项。

  • -x:显示帮助文本以及日志项。

  • -f:从最近的项开始,随着新项的不断添加持续列显日志。非常适合用于检查以较短间隔执行的触发器。按 CtrlC 退出。

9.4 systemd 计时器:弥补错过的轮次

如果 systemd 计时器处于非活动状态或系统在预期执行期间关闭,可以选择性地在计时器再次激活后立即触发错过的事件。要启用此功能,请将配置选项 Persistent=true 添加到 [Timer] 部分:

[Timer]
OnCalendar=Mon..Fri 10:00
Persistent=true
Unit=helloworld.service

9.5 如何从 cron 迁移到 systemd 计时器?

所有 cron 作业都可以迁移到 systemd 计时器。下面是有关迁移 cron 作业的一般说明:

  1. 创建执行脚本的服务文件。有关详细信息,请参见例 1 “服务文件”

  2. 创建执行服务文件的计时器文件。有关一般说明,请参见例 2 “计时器文件”

    1. 转换日历项。cron 和 systemd 中指定时间的方式不相同。使用以下模式作为转换模板:

      Cron:               Minute Hour Day Month DayOfWeek
      systemd: OnCalendar=DayOfWeek Year-Month-Day Hour:Minute:Second

      要测试转换后的日历项,请按照第 5 节 “测试日历项”中的说明操作。

    2. 转换 cron 别名 (@NICK):

      Cron     : systemd timer
      -------- : ----------------------------
      @reboot  : OnBootSec=1s
      @yearly  : OnCalendar=*-01-01 00:00:00
      @annually: OnCalendar=*-01-01 00:00:00
      @monthly : OnCalendar=*-*-01 00:00:00
      @weekly  : OnCalendar=Sun *-*-* 00:00:00
      @daily   : OnCalendar=*-*-* 00:00:00
      @hourly  : OnCalendar=*-*-* *:00:00
    3. 转换变量赋值。systemd 变量赋值必须在 [Service] 部分中定义。不能以这种方式转换 MAILTO - 具体请参见下一步。

      cron: VARIABLE=VALUE
      systemd: Environment="VARIABLE=VALUE"
    4. 按照第 6 节 “当计时器失败时接收电子邮件通知”中的说明设置电子邮件通知,以替换 cron 的 MAILTO 功能。

例 8︰ 从 cron 迁移到 systemd 计时器

下面是在引导后经过 5 分钟并在每个星期一至星期五 10 点调用脚本 helloworld.sh 的 crontab 项:

@reboot sleep 300 && /usr/local/bin/helloworld.sh
0 10 * * * 1-5 /usr/local/bin/helloworld.sh

调用脚本的 systemd 服务文件 (helloworld.service) 如下所示:

[Unit]
Description="Hello World script"
[Service]
ExecStart=/usr/local/bin/helloworld.sh

计时器文件 (helloworld.timer) 如下所示:

[Unit]
Description="Run helloworld.service 5min after boot and at 10am every Mon-Fri"
[Timer]
OnBootSec=5min
OnCalendar=Mon..Fri *-*-* 10:00:*
Unit=helloworld.service
[Install]
WantedBy=multi-user.target

10 更多信息