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 会发生什么?
- systemd 将
myapp解析为myapp.service - 在标准路径中找到
/etc/systemd/system/myapp.service - 检查是否存在启用链接:
ls -l /etc/systemd/system/multi-user.target.wants/myapp.service - 如果存在 → 返回
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。 - 安装软件包时,有些发行版会默认启用某些服务(例如
sshd、cron等),这也会在.wants目录中创建链接。 - 但本质上仍属于上述机制。
(2) 其他 target 的 .wants 目录
- 系统可能启动多个 target(如
graphical.target、network-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.target、sysinit.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/ 的执行时机:
-
~/.bashrc- 在每次启动一个 交互式非登录 shell(interactive non-login shell)时被读取。
- 在大多数终端模拟器(如 Windows Terminal 打开 Ubuntu)中,默认启动的就是这种 shell,所以每次打开终端都会执行
~ ~/.bashrc。 - 因此,如果你把命令写在这里,效果是“每次打开终端都运行一次”,而不是“WSL 启动时运行一次”。
-
/etc/profile.d/*.sh- 这些脚本是在 登录 shell(login shell) 启动时由
/etc/profile自动 source 的。 - 如果你通过
wsl -u username或wsl --exec bash --login等方式启动登录 shell,这些脚本才会执行。 - 普通终端(如直接点击 Ubuntu 图标)默认不启动登录 shell,所以
/etc/profile.d/下的脚本可能不会被执行,除非你显式配置终端以登录模式启动。
- 这些脚本是在 登录 shell(login shell) 启动时由
总结
| 方式 | 触发时机 | 是否“真正开机自启” |
|---|---|---|
~/.bashrc |
每次打开终端(交互式非登录 shell) | ❌ 否 |
/etc/profile.d/*.sh |
登录 shell 启动时(通常不触发) | ❌ 否 |
/etc/wsl.conf → [boot] command |
WSL 实例首次启动时(内核加载后) | ✅ 是(WSL 层面) |

浙公网安备 33010602011771号