首页 / 内容指南 / 当前文章

systemd 的 [Install]、WantedBy、RequiredBy、Alias、Also、DefaultInstance、enable、preset 和 link 有什么区别?

发布于 2026-08-26 · Content Fleet 编辑部

systemd 的 [Install]、WantedBy、RequiredBy、Alias、Also、DefaultInstance、enable、preset 和 link 有什么区别?

一句话结论

[Install]描述启用或禁用时如何创建、移除符号链接,运行时读取unit并不会把这一节当普通依赖执行;WantedBy与RequiredBy建立反向的Wants/Requires链接;Alias创建其他名称;Also让启停用操作连带处理其他unit;DefaultInstance为模板指定默认实例。enable应用安装规则,preset按系统策略决定启用或禁用,link只把搜索路径外的unit引入搜索路径。

Unit 加载与安装是两件事

systemd按unit搜索路径加载配置,解析[Unit][Service]等运行语义。[Install]主要供systemctl enable、disable和相关命令读取。即使没有[Install],一个unit仍可被手动start或被其他依赖拉起,只是可能被报告为static。

[Install] 为什么不直接生效

它是安装元数据,描述应创建哪些符号链接,而不是daemon每次启动服务时动态解释的依赖声明。编辑这一节后必须重新应用enable策略,已有链接不会因为daemon-reload自动重建。

WantedBy 是什么

WantedBy=multi-user.target表示启用该unit时,在目标的.wants/目录创建指向本unit的链接。效果相当于目标拥有Wants=依赖。目标启动时会拉起它,但被拉起unit失败通常不会让目标本身失败。

RequiredBy 是什么

RequiredBy在启用时创建.requires/链接,使目标获得Requires=依赖。它比Wants绑定更强,但仍不要把“需求关系”误解为完整的启动顺序或故障传播规则;顺序需要Before/After等单独表达。

WantedBy 与 Wants 的方向

app.serviceWantedBy=multi-user.target,启用后等价于在multi-user.target一侧加入对app的Wants。[Install]让被依赖unit可以声明反向安装关系,适合软件包提供自己的unit而不直接修改目标文件。

RequiredBy 与 Requires 的方向

同理,worker.service中的RequiredBy=batch.target会在启用后让batch.target要求worker。检查依赖时应查看生成链接和systemctl list-dependencies,不要只搜索worker文件里的Requires=

WantedBy 不等于 After

Wants/Requires决定是否把另一个unit加入事务,After/Before决定两个已加入事务的job顺序。若服务必须在网络就绪后启动,通常要分别考虑拉入关系与顺序关系,单独写WantedBy不能表达“等网络就绪”。

Alias 是什么

Alias声明启用时为unit创建额外名称的符号链接。别名可用于兼容旧服务名、提供通用名称或切换实现。别名必须符合unit类型和命名规则;错误别名可能与已有文件冲突。

Alias 与实例模板

普通unit和模板unit的别名规则不同。模板可以别名到兼容模板名称,实例别名还要保持合法实例语义。不要用Alias绕过模板实例设计,应先验证systemd-analyze verify和实际enable输出。

Also 是什么

Also列出在启用或禁用当前unit时一并处理的其他unit。例如服务、socket和path unit作为一组安装。它影响安装操作,不表示这些unit运行时自动互相启动,也不替代Requires、Wants或触发关系。

Also 的递归风险

多个unit可以互相引用Also,工具会处理关联集合,但复杂链会让管理员难以预测disable范围。建议只用于明确、紧密的安装组合,并在包升级测试中检查将创建和删除的链接。

DefaultInstance 是什么

模板unit名称形如[email protected]。DefaultInstance为没有显式实例名的启用操作提供默认实例,例如把systemctl enable [email protected]解析为预定实例。它不限制还可创建哪些其他实例。

模板与实例的区别

模板文件包含%i等实例说明符,实际运行对象是[email protected]。模板自身通常不能作为无实例的普通服务启动。DefaultInstance只是安装默认值,不是运行时自动发现所有实例的机制。

systemctl enable 做什么

enable读取unit的[Install],在持久配置目录创建相应符号链接,并通常重新加载manager配置。它的主要结果是建立开机或目标激活路径,不保证当前进程已启动。

enable 与 start 的区别

start立即为当前manager提交启动job,但不创建下次启动所需的安装链接;enable创建链接但默认不启动当前服务。需要两者时可显式执行systemctl enable --now name.service,仍应分别验证enabled与active状态。

disable 做什么

disable删除按该unit安装信息创建的相关链接,包括启用链接和别名等。它通常不会停止当前已运行服务。若要立即停止并禁止下次启动,可使用disable --now,同时确认是否还有其他依赖路径会拉起unit。

reenable 何时使用

reenable近似先disable再enable,用于重新应用更新后的[Install]配置。例如包升级改变WantedBy或Alias后,单纯daemon-reload不会迁移旧链接,reenable可清理并按新规则重建。

is-enabled 的状态不只有 enabled

可能看到enabled、enabled-runtime、static、indirect、disabled、masked、generated或transient等状态。脚本不要只解析人类可读输出,应该使用命令退出码并明确允许的状态集合。

static 是什么意思

static通常表示unit没有可供enable使用的安装规则,但仍可由依赖、socket、path、timer、D-Bus或手动start激活。static不是“无法运行”,也不是“已经启用”。

indirect 是什么意思

indirect常与Also或Alias等间接安装关系有关,具体显示取决于unit安装元数据与版本。排查时用systemctl catlist-unit-files和文件系统链接确认,不要仅凭一个状态词修改生产配置。

preset 是什么

preset按preset策略文件中的enable、disable或ignore规则处理unit。它用于发行版或组织表达“默认应启用哪些服务”,而不是取代管理员对单个系统的实时操作。

preset 与 enable 的区别

enable明确执行操作者对指定unit的启用意图;preset先查询匹配规则,再决定启用、禁用或忽略。软件包安装脚本常使用preset以尊重系统默认策略,不应无条件enable覆盖管理员选择。

preset 规则的先匹配语义

preset文件按规定目录和词法顺序合并,通常首个匹配规则决定处理。通配规则若放置不当会覆盖后续意图。组织应给本地策略分配明确优先级文件名,并用测试系统验证结果。

enable、disable 与 ignore

规则中的enable要求按安装信息启用匹配unit,disable要求禁用,ignore表示不改变现状。ignore与disabled不同:前者是不采取动作,后者会移除启用链接。

preset-all 的风险

preset-all可对大量已安装unit应用策略,可能改变现有管理员配置。执行前应审阅策略、使用只读输出或测试环境评估,并准备链接清单备份;不要把它当作无害的daemon-reload。

systemctl link 做什么

link把位于标准unit搜索路径之外的unit文件链接进搜索路径,使manager能够按名称加载它。它不读取[Install]建立目标依赖,也不等于enable。

link 与 enable 的配合

开发或临时测试时,可先link外部绝对路径,再按需start或enable。但生产更适合由包管理器把unit安装到标准目录,避免源文件被移动或删除后留下断链。

--runtime 是什么

enable、mask和部分相关操作可用--runtime把链接写入/run,重启后消失。它适合临时测试或应急,不应被误报为持久配置成功。核验时区分enabled与enabled-runtime。

--global 与 --user

系统manager、当前用户manager和所有用户的全局默认配置是不同范围。--user操作当前用户实例,--global管理所有用户未来实例的全局unit文件状态,但不等于修改已运行用户manager的即时状态。

mask 与 disable 的区别

disable只移除安装启用链接,unit仍可手动或被依赖启动;mask通常把unit名称链接到/dev/null,阻止加载启动。mask是更强的禁止措施,应记录原因并测试依赖影响。

enable 后为何仍没开机启动

检查链接是否指向实际会进入的target,系统默认target是什么,unit是否有Condition失败,依赖事务是否拉入,以及是否被mask。容器或特殊启动环境也可能不走传统multi-user.target路径。

enable 后为何立即没进程

因为enable不等于start。也可能服务是oneshot执行后退出、socket激活尚未触发,或Type与RemainAfterExit造成状态看起来不同。使用systemctl status和journal区分未启动、已退出和失败。

编辑 [Install] 后要做什么

先运行systemd-analyze verify检查unit,执行daemon-reload让manager重新读取文件,再用reenable或disable/enable重建安装链接。最后分别检查is-enabled、依赖图和运行状态。

Drop-in 能修改 [Install] 吗

可以用drop-in覆盖或追加相关设置,但列表指令的清空与追加规则需谨慎。修改后同样必须重新应用安装操作;仅创建drop-in并daemon-reload不会自动移动已存在的.wants/链接。

如何查看生成了哪些链接

enable命令通常显示创建的链接,也可查看/etc/systemd/system/run/systemd/system及用户范围目录。使用systemctl showlist-dependencies --reverse辅助确认,但最终要区分文件安装关系与运行时自动依赖。

软件包升级注意事项

供应商unit通常位于/usr/lib/lib,管理员覆盖应放/etc的drop-in而非直接改供应商文件。升级改变Install规则时,包脚本应遵循发行版preset和管理员选择,避免悄悄重新启用已禁用服务。

Vendor preset 状态怎么看

systemctl statuslist-unit-files可能同时展示当前启用状态和vendor preset。前者说明本机现有符号链接结果,后者说明按供应商策略重新执行preset时倾向启用还是禁用。两者不同并不必然是故障:管理员可以有意禁用供应商默认启用的服务,也可以启用默认关闭的组件。审计工具应分别记录这两个维度,不能看到preset为disabled就宣称当前服务未启用。

克隆主机为何会带来错误链接

直接复制/etc/systemd/system可能把源主机的启用、别名和mask链接一并带到新机器,而目标机器安装的软件包或默认target并不相同。制作镜像时应由声明式配置重新应用enable或preset,并检查断链、指向不存在unit的别名以及仅应存在于/run的临时状态,避免把一次应急操作固化进所有新实例。

最小示例

[Unit]
Description=Example worker
After=network-online.target
Wants=network-online.target

[Service]
Type=exec
ExecStart=/usr/local/bin/example-worker

[Install]
WantedBy=multi-user.target
Alias=example.service

启用时会为multi-user.target建立Wants链接并创建别名;After/Wants则是运行依赖与顺序。四者虽然写在同一文件,却在不同阶段发挥作用。

安全变更流程

保存当前unit与链接清单,在测试环境验证目标和依赖,再部署文件、verify、daemon-reload、reenable,最后检查enabled与active。若是关键服务,还应验证重启机器后的真实启动路径,而非只看当前会话。

FAQ

1. 写了 WantedBy 后还必须 enable 吗?

通常必须。WantedBy只是描述enable时创建什么链接,本身不会自动创建链接。

2. enable 会自动 start 服务吗?

默认不会。需要当前立即启动时使用start或enable --now

3. static unit 是配置错误吗?

不一定。它可能设计为被其他unit、socket、timer或手动操作激活。

4. Also 是否会让两个服务一起运行?

不会直接保证。它连带处理启用与禁用;运行关系需用依赖或触发机制表达。

5. preset 会覆盖管理员选择吗?

执行preset可能按策略启用或禁用unit,因此要了解发行版包脚本和本地preset规则,避免随意运行preset-all。

6. link 后为什么 is-enabled 仍不是 enabled?

link只将外部unit纳入搜索路径,没有按[Install]创建目标依赖链接。

7. 修改 WantedBy 后 daemon-reload 足够吗?

不够。daemon-reload重读配置,但旧安装链接需通过reenable或disable/enable重建。

8. RequiredBy 能保证服务先启动吗?

不能单独保证顺序。它建立需求关系,先后顺序还要用Before/After表达。

systemd官方资料

  • https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html
  • https://www.freedesktop.org/software/systemd/man/latest/systemctl.html
  • https://www.freedesktop.org/software/systemd/man/latest/systemd.preset.html
  • https://www.freedesktop.org/software/systemd/man/latest/systemd.special.html
  • https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html
  • https://www.freedesktop.org/software/systemd/man/latest/systemd.directives.html

最终排障原则

先分别问三个问题:unit能否被加载、是否已建立持久启用链接、当前是否正在运行。用[Install]和enable/preset回答第二个问题,用start与运行状态回答第三个问题,用搜索路径与link回答第一个问题。只有把安装、依赖、顺序和运行状态拆开,才能避免“enabled却没启动”或“disabled却仍被拉起”的误判。