systemd相关知识

systemd识别服务和设置自启服务的行为解析

当你执行

systemctl is-enabled 服务名

时,systemd 会查找名为 服务名.service 的单元文件(unit file)。如果这个文件存在于 systemd 的标准搜索路径中,systemd 就认为“这是一个合法的服务”,然后检查它是否被启用(即是否有符号链接指向它)。


🧩 详细解释:systemd 如何“知道”一个名字是一个服务?

1. 服务名 → 单元文件名

  • 当你输入 nginx,systemd 默认会在内部将其补全为 nginx.service
  • 因为 .service默认单元类型,所以可以省略后缀。
  • 其他类型如 .socket.timer.target 等则必须显式写出(除非上下文明确)。

✅ 所以 systemctl is-enabled nginx 实际等价于 systemctl is-enabled nginx.service


2. systemd 在哪些地方找单元文件?

systemd 按优先级从高到低搜索以下目录:

路径 用途
/etc/systemd/system/ 系统管理员自定义或覆盖的单元文件(最高优先级)
/run/systemd/system/ 运行时生成的单元(如临时服务),重启后消失
/usr/lib/systemd/system/(或 /lib/systemd/system/ 软件包安装的官方单元文件(如 apt install nginx 会放在这里)

💡 例如:

  • nginx 的单元文件通常由包管理器安装在 /usr/lib/systemd/system/nginx.service
  • 如果你在 /etc/systemd/system/ 下也放了一个同名文件,它会覆盖系统默认的

3. “注册为服务”的本质:提供一个 .service 单元文件

要让你的程序“成为一个 systemd 服务”,你需要:

✅ 步骤 1:创建一个 .service 文件

例如:/etc/systemd/system/myapp.service

[Unit]
Description=My Custom Application
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/myapp
Restart=always
User=myuser

[Install]
WantedBy=multi-user.target

✅ 步骤 2:重载 systemd 配置

sudo systemctl daemon-reload

⚠️ 这一步很重要!否则 systemd 不知道新服务的存在。

✅ 步骤 3:启用服务(可选,用于开机自启)

sudo systemctl enable myapp

这会在 /etc/systemd/system/multi-user.target.wants/ 下创建一个符号链接。


4. 此时执行 systemctl is-enabled myapp 会发生什么?

  1. systemd 将 myapp 解析为 myapp.service
  2. 在标准路径中找到 /etc/systemd/system/myapp.service
  3. 检查是否存在启用链接:
    ls -l /etc/systemd/system/multi-user.target.wants/myapp.service
    
  4. 如果存在 → 返回 enabled;否则 → 返回 disabled(但依然知道这是一个服务!)

❗ 如果根本找不到 myapp.service 文件,你会看到:

systemctl is-enabled nonexistent
# 输出: nonexistent.service is not found.

📌 关键总结

问题 答案
如何让系统“认识”一个服务名? 在 systemd 的单元搜索路径中提供一个 服务名.service 文件
systemctl is-enabled 如何工作? 先确认 .service 文件是否存在,再检查是否被 enable(即是否有符号链接)
“注册服务”需要做什么? .service 文件 + daemon-reload
服务名是否区分大小写? 是,但通常全小写(Linux 文件系统大小写敏感)

systemd开机自动启动的服务来源的进一步说明

在使用 systemd 作为初始化系统的 Linux 发行版(如 CentOS 7+、Ubuntu 16.04+ 等)中,开机自动启动的服务并不仅限于 /etc/systemd/system/multi-user.target.wants/ 目录下的软链接服务,但该目录确实是最常见和主要的机制之一

下面详细说明:


✅ 1. /etc/systemd/system/multi-user.target.wants/ 的作用

  • 这个目录包含指向实际 .service 文件的符号链接
  • 当系统进入 multi-user.target(相当于传统的运行级别 3,即多用户文本模式)时,systemd 会启动该目录下所有列出的服务。
  • 使用 systemctl enable your-service.service 命令启用服务时,通常会在对应 target 的 .wants 目录(如 multi-user.target.wants)中创建一个软链接。

因此,这是用户或管理员手动启用服务后最常见的自动启动方式。


✅ 2. 其他可能自动启动服务的来源

(1) 默认启用的服务(来自软件包)

  • 某些服务单元文件中包含 [Install] 段,并设置 WantedBy=multi-user.target
  • 安装软件包时,有些发行版会默认启用某些服务(例如 sshdcron 等),这也会在 .wants 目录中创建链接。
  • 但本质上仍属于上述机制。

(2) 其他 target 的 .wants 目录

  • 系统可能启动多个 target(如 graphical.targetnetwork-online.target 等)。
  • 如果服务被启用到其他 target(如 graphical.target.wants),且该 target 被激活,服务也会启动。
  • 例如桌面环境的服务可能在 graphical.target.wants/ 中。

(3) 依赖关系自动拉起(Implicit Dependencies)

  • 即使一个服务没有被显式启用(即不在任何 .wants 目录中),但如果其他已启用的服务依赖它(通过 After=Requires=Wants= 等),它也可能在启动时被自动拉起。
  • 这类服务不会出现在 .wants 目录中,但依然会随系统启动。

(4) 由 socket、path、timer 等 unit 触发

  • systemd 支持基于事件的启动(如 socket 激活)。
  • 例如 ssh.socket 可以按需启动 sshd.service,即使 sshd.service 本身未被启用。
  • 这类服务不是“开机立即启动”,而是在特定条件满足时启动,但仍属于“系统启动过程中可能运行”的范畴。

(5) /etc/systemd/system/ 下的本地覆盖或自定义 unit

  • 如果你直接将 .service 文件放在 /etc/systemd/system/ 并启用它,也会被识别。
  • 但启用后通常仍会创建 .wants 链接。

(6) DefaultDependencies=yes 和内置依赖

  • 某些关键服务(如 basic.targetsysinit.target 的一部分)由 systemd 内部逻辑管理,不一定依赖 .wants

✅ 如何查看所有开机启动的服务?

# 查看所有已启用(开机启动)的单元
systemctl list-unit-files --type=service --state=enabled

# 查看当前 target(如 multi-user.target)下要启动的所有服务
systemctl list-dependencies multi-user.target

# 查看某个服务是否被其他服务依赖而启动
systemctl list-dependencies --reverse your-service.service

✅ 总结

不是只有 /etc/systemd/system/multi-user.target.wants/ 下的软链接服务才会在开机时启动,但:

  • 该目录是显式启用服务的主要体现;
  • 其他机制(依赖、socket 激活、其他 target 等)也可能导致服务在启动时运行;
  • 最准确的方式是使用 systemctl list-unit-files --state=enabled 或分析依赖关系。

~/.bashrc/etc/profile.d/的对比

关于 ~/.bashrc/etc/profile.d/ 的执行时机:

  1. ~/.bashrc

    • 在每次启动一个 交互式非登录 shell(interactive non-login shell)时被读取。
    • 在大多数终端模拟器(如 Windows Terminal 打开 Ubuntu)中,默认启动的就是这种 shell,所以每次打开终端都会执行 ~ ~/.bashrc
    • 因此,如果你把命令写在这里,效果是“每次打开终端都运行一次”,而不是“WSL 启动时运行一次”。
  2. /etc/profile.d/*.sh

    • 这些脚本是在 登录 shell(login shell) 启动时由 /etc/profile 自动 source 的。
    • 如果你通过 wsl -u usernamewsl --exec bash --login 等方式启动登录 shell,这些脚本才会执行。
    • 普通终端(如直接点击 Ubuntu 图标)默认不启动登录 shell,所以 /etc/profile.d/ 下的脚本可能不会被执行,除非你显式配置终端以登录模式启动。

总结

方式 触发时机 是否“真正开机自启”
~/.bashrc 每次打开终端(交互式非登录 shell) ❌ 否
/etc/profile.d/*.sh 登录 shell 启动时(通常不触发) ❌ 否
/etc/wsl.conf[boot] command WSL 实例首次启动时(内核加载后) ✅ 是(WSL 层面)
posted @ 2026-01-14 16:46  kksk43  阅读(1)  评论(0)    收藏  举报
特效
黑夜
侧边栏隐藏