我已阅读什么是 multi-user.target和systemd 文档,其中指出 multi-user.target 是一个特殊目标。此外,许多systemd 示例都包含该行。
- 为什么这么多示例服务包含该行?
- 如果它们不包含 WantedBy=multi-user.target 会发生什么?
- 你能给我一个例子,说明什么时候实际上不建议将该行包含在服务文件定义中?
- 同样,什么时候保留这条线是个好主意?
我已阅读什么是 multi-user.target和systemd 文档,其中指出 multi-user.target 是一个特殊目标。此外,许多systemd 示例都包含该行。
1.)
multi-user.target
基本上是最接近经典 SysVinit 运行级别 3 的等价物systemd
。当systemd
系统启动时,systemd
试图使系统状态与default.target
- 指定的状态相匹配,这通常是graphical.target
或的别名multi-user.target
。multi-user.target
通常定义一个系统状态,其中所有网络服务都已启动并且系统将接受登录,但未启动本地 GUI。这是服务器系统的典型默认系统状态,可能是远程服务器机房中的机架式无头系统。graphical.target
是另一个可能的别名default.target
。通常它被定义为 的超集multi-user.target
:它包括所做的一切multi-user.target
,以及本地 GUI 登录的激活。有点像经典 SysVinit 中的运行级别 5。服务中的行
WantedBy=multi-user.target
本质上与在 SysVinit 系统中指定“此服务应在运行级别 3、4 和 5 中启动”相同:它systemd
表明该服务应作为正常系统启动的一部分启动,无论是否本地GUI 处于活动状态。但是,
WantedBy
它与启用/禁用状态是分开的:所以在另一种意义上,它是一种“预设”:它决定了在什么条件下可能会发生自动启动,但仅限于首先启用服务时。2.) 如果您省略该
WantedBy=multi-user.target
行并且没有其他启用的服务在其服务定义中包含Requires=your.service
或Wants=your.service
,您的服务将不会自动启动。systemd
适用于依赖项,并且在启动时,如果没有任何内容Requires
或Wants
您的服务,即使启用了该服务,它也不会启动。当然,您可以编辑您
default.target
的添加或删除Requires
或Wants
任何您希望在启动时启动的服务的行 - 但这样您就可以将一个新的服务文件放入系统并使其默认工作(这使得软件非常容易包管理器),systemd
具有WantedBy
andRequiredBy
关键字,可用于从“另一端”插入Wants
和Requires
键入依赖项(分别)。3.) 如果您不希望该服务在启动时自动启动,或者该服务是您明确定义的依赖链的一部分,您应该省略该行。
例如,您可能正在重构服务器应用程序 A,并且出于某种原因决定将一些可选功能从它拆分为单独的服务 B,以允许用户在不需要时选择不安装它。然后,您可以使服务 B 成为单独的
service-B.rpm
,并定义B.service
withWantedBy=A.service
以systemd
在服务 A 启动时自动启动服务 B - 但仅在service-B.rpm
实际安装时。请注意,a
Wants
orWantedBy
仅表示系统应该在另一个服务或目标也启动时启动一个服务,但它根本没有指定启动/关闭顺序。如果您需要在服务 A 启动时服务 B 已经在运行,则需要Before=A.service
在B.service
文件中添加以明确指定启动顺序依赖项。4.) 任何时候您确实希望服务能够在启动时自动启动,并且没有其他依赖项已经定义。
如果您删除
WantedBy=multi-user.target
,那么systemctl enable your-example-here
将(嘈杂地)无法做任何事情。图形目标
如果从源安装纯 systemd,它引导到的“默认目标”是
graphical.target
.开始
graphical.target
开始multi-user.target
,加上提供图形用户界面所需的任何单元。这种额外的复杂性是为了模仿传统的“运行级别”而安排的。您真的应该忽略/掩盖“运行级别”仿真;无论如何它都不能正常工作。对不起!我想在历史上强调“图形”与“多用户”的原因是图形软件 1)不像系统的其他部分那样强大和成熟,2)需要大量资源。
通常只有少数单位是特定于
graphical.target
. GUI 本身只有一个服务,例如gdm.target
. 这里还有一些主要由 GUI 使用的支持服务。编辑:谷歌搜索建议如果您没有安装 GUI,但“默认目标”已保留为
graphical.target
,则 systemd 可能会记录警告。“无法为单元 display-manager.service 添加依赖项作业,忽略:单元 display-manager.service 加载失败:没有这样的文件或目录。” 我们希望避免在日志中乱扔不必要的警告。因此,如果您没有安装 GUI,最好使用systemctl set-default multi-user
. 尽管您的操作系统的安装系统可能已经为您解决了这个问题。除此之外,我强烈赞成在这件事上冷漠:-)。系统初始化目标
一些服务和其他类型的单元“参与早期启动”。它们被定义为
Before=sysinit.target
直接或间接开始。大多数服务只是启动After=sysinit.target
- 这是自动的情况,除非服务设置DefaultDependencies=no
.多用户.target
大多数示例服务不属于上述任何一个类别,因此我们将它们附加到
multi-user.target
. 这包括大多数网络服务(例如网络服务器),它们是原型系统服务。动态激活服务
您可能会看到的另一种可能性是在引导时未自动启动的服务单元。所以就不需要了
WantedBy=multi-user.target
。该服务可以由其他东西触发或“激活”。这方面的一个例子是 dbus 激活服务。当对服务进行 dbus 调用时,可以将 Dbus 配置为按需启动服务。
对于网络服务,您可以使用套接字激活的服务。这可能更容易找到详细信息,因为所有配置都在 systemd 单元中。例如
sshd.socket
或ssh.socket
通常可用于激活[email protected]
或[email protected]
。虽然,我认为在启动时启动 sshd 服务更为常见。与往常一样,上述内容简化并省略了似乎不需要的细节。
是
multi-user.target
一个语义名称,即它与一个含义相关联。请允许我用一个反例来说明这个概念。我将论证使用的决定multi-user.target
取决于上下文。如果您要创建 systemd用户单元配置而不是系统单元配置,您可能会天真地遵循 systemd 系统单元的约定并使用
multi-user.target
1。反例说明
考虑文件
/home/jonathan/.config/systemd/user/coolstuff.service
该用户将仅用于 user
jonathan
,因此将我的目标称为“multi-user.target”几乎没有意义。请注意我是如何选择使用
WantedBy=
user.target 的。这是因为此上下文的范围是我的用户帐户,因此我选择使用我自己的语义约定。换句话说,多个用户不会受到这个单元的影响。然而,在系统级别,由于并行启动顺序,遵循标准化约定更有意义。在启动期间,许多程序会集中在多个目标上。它multi-user.target
在语义上与“为用户参与/与系统交互而读取”的概念相关联(没有像电信公司提到的窗口系统),因此对于大多数系统单元文件来说它是一个安全的选择。脚注