最准的方法是运行 systemctl list-unit-files --type=service --state=enabled,它直接读取 systemd 单元文件的启用标记,不依赖当前运行状态或服务依赖关系,能准确反映系统承诺开机拉起的服务列表。

systemctl list-unit-files --type=service 是最准的依据
它直接读取 systemd 单元文件里的 WantedBy= 或 RequiredBy= 设置,不依赖当前运行状态,也不受 SysV 兼容层干扰。只要服务被 systemctl enable 过,就会在这里标记为 enabled。
常见错误是只看 systemctl list-units --state=active,结果漏掉那些配置了开机自启但当前没跑的服务(比如刚装完还没 reboot 的 nginx.service)。
- 只看启用项:
systemctl list-unit-files --type=service --state=enabled - 排除无意义的
static项(如syslog.socket):systemctl list-unit-files --type=service | awk '$2 == "enabled" && $1 !~ /\.socket|\.timer$' - 加
--no-pager防止输出被截断:systemctl list-unit-files --type=service --state=enabled --no-pager
从 /etc/systemd/system/multi-user.target.wants/ 看实际链接
这个目录下的符号链接,就是 systemctl enable 真正落地的操作痕迹。每个链接指向 /usr/lib/systemd/system/xxx.service 或 /etc/systemd/system/xxx.service,代表该服务被明确加入 multi-user.target 启动链。
容易踩的坑:有人手动在 /etc/systemd/system/ 下放了个 service 文件却没执行 enable,它不会出现在这个目录里,也不会开机启动——systemd 只认链接,不认“放着就等于启用”。
- 列出所有已启用的软链接:
ls -l /etc/systemd/system/multi-user.target.wants/ - 检查某个服务是否真有链接:
ls /etc/systemd/system/multi-user.target.wants/nginx.service 2>/dev/null || echo "not linked" - 注意:有些服务可能链接到
graphical.target.wants/,比如桌面环境相关服务
systemctl is-enabled 判断单个服务最可靠
脚本或自动化排查时,systemctl is-enabled xxx.service 返回值是机器可读的:enabled、disabled、masked、static。比 grep 文本更稳,不受终端宽度或 locale 影响。
别用 systemctl status xxx 的输出去解析“enabled”字样——它的 Loaded: 行里虽然带 enabled,但那是 vendor preset + 当前设置的混合结果,容易误判。
- 查 nginx:
systemctl is-enabled nginx.service - 批量查几个关键服务:
for s in sshd chronyd firewalld; do printf "%-12s: %s\n" "$s" "$(systemctl is-enabled "$s.service" 2>/dev/null)"; done -
masked表示被彻底禁用(systemctl mask),连手动 start 都会失败
旧系统里 chkconfig 和 /etc/rc.d/ 仍需留意
CentOS 7.9、RHEL 7 等仍在广泛使用的系统,部分服务(尤其是第三方或自建脚本)可能走的是 SysVinit 路径。此时 chkconfig --list 和 /etc/rc.d/rc3.d/ 下的 Sxx* 链接才是真实入口。
但要注意:如果同名服务同时存在 systemd unit 和 SysV init script,systemd 会优先使用 unit;SysV 配置可能被忽略,chkconfig 输出里显示 on 也不代表真会启动。
- 查传统服务启用状态:
chkconfig --list | awk '$2~/^on$/ {print $1}' - 看 runlevel 3 的启动脚本:
ls /etc/rc.d/rc3.d/S* - 确认某服务是否由 systemd 托管:
systemctl list-unit-files | grep "^$svc\.service",有结果就别信chkconfig
真正麻烦的不是命令记不住,而是混用 systemd 和 SysV 的系统里,同一个服务可能有两套启用逻辑,而只有 systemctl list-unit-files 和对应 .wants/ 目录能反映最终生效的那一条路径。


















