使用 systemd
计时器
- 解释
从定期运行备份脚本,到计算机引导后立即启动特定进程,Linux 系统上有大量的任务需要调度。
systemd
计时器提供了一个灵活的机制用于调度及管理作业和服务。- 原因
本文旨在提供
systemd
计时器的完整概述,涵盖创建、维护、测试、查错以及从 cron 迁移等方面的信息。- 工作量
创建示例
systemd
计时器需要 10 分钟。最多花费 30 分钟即可完全了解systemd
计时器的工作原理。- 要求
基本了解
systemd
。root
或 sudo 特权。要以普通用户的身份使用systemd
计时器,请先参见第 7 节 “以普通用户身份使用计时器”。
1 systemd
计时器概念 #
systemd
计时器单元提供一个用于在 Linux 上调度作业的机制。这些作业的执行时间可以基于时间和日期或基于事件。
systemd
计时器单元通过 .timer
文件扩展名标识。每个计时器文件都需要一个由它控制的相应服务文件。也就是说,计时器文件将激活并管理相应的服务文件。systemd
计时器支持以下功能:
使用计时器单元安排的作业可以依赖其他
systemd
服务。计时器单元被视为常规systemd
服务,因此可以使用systemctl
进行管理。计时器可以是实时的(基于日历事件触发),也可以是单调性的(自特定起始时刻经过指定的时间后触发)。
时间单元将记录到系统日记中,这样用户便能更轻松地对时间单元进行监控和查错。
计时器使用集中式
systemd
管理服务。如果系统在预期执行期间关闭,则一旦系统再次运行,就会执行计时器。
2 创建计时器 #
以下示例说明如何设置下面这样的计时器:在引导后触发 helloworld.sh
外壳脚本,并相对于其激活时间每隔 24 小时重复执行一次。此外,计时器会在星期一至星期五上午 10 点运行。
2.1 Hello World 示例 #
创建包含以下内容的
/etc/systemd/system/helloworld.service
文件:[Unit] Description="Hello World script" [Service] ExecStart=/usr/local/bin/helloworld.sh
这是一个
systemd
服务文件,告知systemd
要运行哪个应用程序。创建包含以下内容的
/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
这是计时器文件,用于控制相应服务文件的激活。
校验您先前创建的文件是否不含错误:
>
systemd-analyze verify /etc/systemd/system/helloworld.*如果命令未返回任何输出,则表示文件成功通过了校验。
启动计时器:
>
sudo
systemctl start helloworld.timer仅针对当前会话激活计时器。
启用计时器以确保在引导时将其激活:
>
sudo
systemctl enable helloworld.timer
2.2 示例解释 #
[Unit] Description="Hello World script"1 [Service] ExecStart=/usr/local/bin/helloworld.sh2
要使服务文件能够正常运行,至少需要指定 [Unit]
和 [Service]
部分。systemd
服务文件通常包含 [Install]
部分,该部分用于确定要加载的一个或多个服务目标。计时器的服务文件中不需要此部分,因为此信息已在计时器文件中提供。有关高级配置,请参见Managing
systemd
targets with systemctl。
[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
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
要列出系统上所有可用的计时器,请使用 systemctl list-timers
。下列选项可用:
- 列出所有活动计时器:
>
sudo
systemctl list-timers- 列出所有计时器,包括非活动的计时器:
>
sudo
systemctl list-timers --all- 列出与模式匹配的所有计时器:
>
sudo
systemctl list-timers PATTERN>
sudo
systemctl list-timers --allPATTERNPATTERN 必须是一个名称或外壳通配表达式。可以使用运算符
*
、?
和[]
。有关通配模式的详细信息,请参见man 7 glob
。- 列出与特定状态匹配的计时器:
>
sudo
systemctl list-timers --state=STATESTATE 接受以下值:
active
、failed
、load
、sub
。有关详细信息,请参见man systemctl
。
运行任何 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
4 计时器类型 #
systemd
支持两种类型的计时器:实时(基于日历)和单调(基于事件)。尽管计时器通常是永久性的,但 systemd
还允许设置仅对当前会话有效的瞬态计时器。
- 实时计时器
实时计时器由日历事件触发。它们是使用选项
OnCalendar
定义的。您可以基于日期和时间指定何时触发事件。使用以下模板:
OnCalendar=DayOfWeek1 Year-Month-Day2 Hour:Minute:Second3
星期日期。可能的值为
Sun
、Mon
、Tue
、Wed
、Thu
、Fri
、Sat
。留空会忽略星期日期。日期。用两位数指定月和日,用四位数指定年。可以用通配符
*
替换每个值,以匹配每个出现的值。时间。用两位数指定每个值。可以用通配符
*
替换每个值,以匹配每个出现的值。适用于所有值:用两个点定义连续范围 (
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
,其中提供了有关以下主题的其他信息:缩短语法并使用缩写
指定重复次数
查找特定的月份日期(月份的最后一日、最后一个星期日等)
应用时区
- 单调计时器
单调计时器在发生特定事件(例如系统引导或系统单元激活事件)后经过指定的时间时触发。值按时间单位(分钟、小时、日、月、年等)定义。支持以下单位:
usec
、msec
、seconds
、minutes
、hours
、days
、weeks
、months
、years
。可以使用多个选项来定义单调计时器: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 类似的功能。以下过程介绍了当计时器失败时启用电子邮件通知的解决方法。
该过程包括以下步骤:
创建一个用于发送电子邮件的脚本。
创建运行电子邮件脚本的
systemd
服务文件。测试电子邮件服务文件。
在计时器控制的服务中,通过
OnFailure
调用创建的电子邮件服务文件。
以下示例将使用软件包 mailx 中的 mailx
命令。这需要安装并正确配置 Postfix 电子邮件服务器。
创建脚本
/usr/local/bin/send_systemd_email
。该脚本需要两个参数:
$1
(电子邮件地址)和$2
(收到的失败通知所对应服务文件的名称)。这两个参数均由运行邮件脚本的单元文件提供。#!/bin/sh systemctl status --full "$2" | mailx -S sendwait\ -s "Service failure for $2" -r root@$HOSTNAME $1
确保该脚本可执行:
>
sudo
chmod 755 /usr/local/bin/send_systemd_email
创建文件
/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
将文件中的 USER 和 EMAIL_ADDRESS 分别替换为要接收电子邮件的用户的登录名和电子邮件地址。
%i
是失败的服务的名称(它将通过%n
参数传递给电子邮件服务)。校验服务文件并修复报告的问题:
>
systemd-analyze verify /etc/systemd/system/send_email_to_USER@.service如果命令未返回任何输出,则表示文件成功通过了校验。
要校验整个过程,请使用
dbus
实例启动服务进行测试。(可以使用当前正在运行的任何其他服务。本示例之所以使用 dbus,是因为该服务肯定可以在任何安装的系统上运行。)>
sudo
systemctl start send_email_to_USER@dbus.service如果成功,EMAIL_ADDRESS 会收到一封电子邮件,其主题为
Service failure for dbus
,正文包含 dbus 状态消息。(这只是一项测试,dbus 服务本身并未出现问题。您可以放心删除该电子邮件,无需执行任何操作)。如果测试电子邮件已成功发送,请将其集成到您的服务文件中。
要向服务添加电子邮件通知,请将
OnFailure
选项添加到在发生失败时用于接收通知的服务文件的Unit
部分:[Unit] Description="Hello World script" OnFailure1=send_email_to_USER2@%n3.service [Service] ExecStart=/usr/local/bin/helloworld.sh
您已成功为 systemd
服务设置失败通知。
电子邮件服务文件已将收件人的电子邮件地址硬编码。要向其他用户发送通知电子邮件,请复制电子邮件服务文件,并替换文件名中的用户登录名,以及抄送行中的电子邮件地址。
要同时向多个收件人发送失败通知,请将相应的服务文件添加到该服务文件(使用空格作为分隔符):
OnFailure=send_email_to_tux@%n.service send_email_to_wilber@%n.service
7 以普通用户身份使用计时器 #
普通用户也可以使用 systemd
计时器。这些计时器可帮助您自动完成重复性任务,例如备份、处理图像或将数据移到云中。
适用于系统范围计时器的过程和任务同样适用于 systemd 计时器。但是,两者存在以下差异:
计时器和服务文件必须放在
~/.config/systemd/user/
中。必须结合
--user
开关运行所有systemctl
和journalctl
命令。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 “服务文件”。
创建执行服务文件的计时器文件。有关一般说明,请参见例 2 “计时器文件”。
转换日历项。cron 和
systemd
中指定时间的方式不相同。使用以下模式作为转换模板:Cron: Minute Hour Day Month DayOfWeek systemd: OnCalendar=DayOfWeek Year-Month-Day Hour:Minute:Second
要测试转换后的日历项,请按照第 5 节 “测试日历项”中的说明操作。
转换 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转换变量赋值。
systemd
变量赋值必须在[Service]
部分中定义。不能以这种方式转换MAILTO
- 具体请参见下一步。cron: VARIABLE=VALUE systemd: Environment="VARIABLE=VALUE"
按照第 6 节 “当计时器失败时接收电子邮件通知”中的说明设置电子邮件通知,以替换 cron 的 MAILTO 功能。
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
将静默忽略这些错误。例如:
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
:从最近的项开始,随着新项的不断添加持续列显日志。非常适合用于检查以较短间隔执行的触发器。按 Ctrl–C 退出。
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 “服务文件”。
创建执行服务文件的计时器文件。有关一般说明,请参见例 2 “计时器文件”。
转换日历项。cron 和
systemd
中指定时间的方式不相同。使用以下模式作为转换模板:Cron: Minute Hour Day Month DayOfWeek systemd: OnCalendar=DayOfWeek Year-Month-Day Hour:Minute:Second
要测试转换后的日历项,请按照第 5 节 “测试日历项”中的说明操作。
转换 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转换变量赋值。
systemd
变量赋值必须在[Service]
部分中定义。不能以这种方式转换MAILTO
- 具体请参见下一步。cron: VARIABLE=VALUE systemd: Environment="VARIABLE=VALUE"
按照第 6 节 “当计时器失败时接收电子邮件通知”中的说明设置电子邮件通知,以替换 cron 的 MAILTO 功能。
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 更多信息 #
有关
systemd
计时器的完整参考,包括高级配置选项(例如延迟或者处理时钟或时区更改),请参见man 5 systemd.timer
。
11 法律声明 #
版权所有 © 2006–2024 SUSE LLC 和贡献者。保留所有权利。
根据 GNU 自由文档许可证 (GNU Free Documentation License) 版本 1.2 或(根据您的选择)版本 1.3 中的条款,在此授予您复制、分发和/或修改本文档的权限;本版权声明和许可证附带不可变部分。许可版本 1.2 的副本包含在题为“GNU Free Documentation License”的部分。
有关 SUSE 商标,请参见 https://www.suse.com/company/legal/。所有其他第三方商标分别为相应所有者的财产。商标符号(®、™ 等)代表 SUSE 及其关联公司的商标。星号 (*) 代表第三方商标。
本指南力求涵盖所有细节,但这不能确保本指南准确无误。SUSE LLC 及其关联公司、作者和译者对于可能出现的错误或由此造成的后果皆不承担责任。