systemctl 列出服务:Linux 服务清单的全部方法
- 2026年9月12日
- 09:00
- 作者: Adrien Roche
- 教程

必须掌握的一条命令:systemctl list-units --type=service
在任何运行 systemd 的发行版上——Ubuntu 15.04 起、Debian 8 起、RHEL 与 CentOS 7 起,以及 Fedora、Arch 和 openSUSE——每个服务都是一个 systemd 单元,而 systemctl 就是列出它们的工具:
systemctl list-units --type=service
默认情况下,它会打印 systemd 当前保存在内存中的所有服务单元:处于活动状态的、有排队任务的,以及失败的服务。它不会显示已安装但从未启动过的服务。当输出超过终端高度时,systemctl 会把它送入分页器(less)——按 q 退出,或加上 --no-pager 直接输出到标准输出。
每一行包含五列:
- UNIT —— 单元名称,例如
ssh.service。这正是你要传给systemctl status、start和stop的名称。 - LOAD —— 单元文件是否被正确解析:
loaded、not-found、bad-setting、error或masked。 - ACTIVE —— 高层状态:
active、inactive、activating、deactivating或failed。 - SUB —— 与单元类型相关的底层状态:一个服务可以是
running、exited、dead等。 - DESCRIPTION —— 单元文件中便于阅读的描述文字。
要把 ACTIVE/SUB 这一对状态放在一起读:active (running) 表示此刻有进程存活,而 active (exited) 表示某个 oneshot 服务已成功执行完毕——这对初始化任务来说很正常,并不是需要修复的问题。
过滤:运行中、失败,还是全部
--state= 参数可以按任意 LOAD、ACTIVE 或 SUB 值过滤,并支持用逗号分隔的列表:
# Only services with a live process
systemctl list-units --type=service --state=running
# Everything loaded, including stopped and dead services
systemctl list-units --type=service --all
# Only failures
systemctl list-units --type=service --state=failed
# Combine states
systemctl list-units --type=service --state=running,exited
systemctl --failed 是失败过滤的内置简写,登录任何一台机器后都值得条件反射式地跑一遍。若需要便于机器解析的输出,--no-legend 会去掉表头和汇总行,--plain 会去掉行首的圆点符号,这样列的位置对 awk 或 cut 来说更稳定。要按名称搜索,可以管道给 grep:systemctl list-units --type=service --all --no-pager | grep ssh。
开机会启动什么:systemctl list-unit-files
list-units 回答的是“现在有什么在运行?”。要回答“开机时会启动什么?”,就要列出磁盘上安装的单元文件:
systemctl list-unit-files --type=service
systemctl list-unit-files --type=service --state=enabled
这里的 STATE 列描述的是开机配置,而不是运行时状态:
enabled—— 开机自动启动(对于由 socket/timer 激活的服务,则在其触发条件下启动)。disabled—— 已安装,但没有任何机制自动启动它。static—— 没有[Install]段;它只作为其他单元的依赖运行,无法直接启用。masked—— 被符号链接到/dev/null;systemd 会完全拒绝启动它。generated—— 由生成器在运行时创建,通常来自遗留的 init 脚本。
较新的 systemd 版本还会打印一个预设列(视版本而定为 VENDOR PRESET 或 PRESET),显示发行版的默认设置是什么。需要避开的陷阱是:enabled 不等于正在运行,disabled 也不等于已停止。一个服务可能是 disabled 却在运行,因为有人手动启动了它;也可能是 enabled 却已经死掉,因为它崩溃了。当这一点很关键时,请把两份清单交叉核对。
单个服务:status、is-active、is-enabled
当某个服务引起你注意时,就放大细看:
systemctl status nginx
systemctl is-active nginx # prints: active | inactive | failed
systemctl is-enabled nginx # prints: enabled | disabled | static | masked
systemctl is-failed nginx
status 会展示完整画面:ACTIVE/SUB 状态、主 PID、运行时长、内存占用、cgroup 进程树,以及最后十行日志。当十行不够用时,直接用 journalctl -xeu nginx 查看日志(-u 按单元过滤,-e 跳到末尾,-x 补充解释性文字)。
is-* 系列命令是为脚本设计的:它们只打印一个词,并相应地设置退出码——is-active 仅当单元处于活动状态时退出码为 0,而 is-enabled 对 disabled 或 masked 的单元返回非零。加上 --quiet 可以隐藏输出,只保留退出码。
上面所有列出类命令都可以用非特权用户执行。真正管理服务——start、stop、enable、disable——需要 root 权限,因此在超越“只读状态”之前,你需要了解 Ubuntu 上 sudo 与切换用户的工作方式。另外请注意,用户级单元属于另一个独立的管理器:systemctl --user list-units --type=service 列出的是在你自己会话中运行的服务,这也解释了为什么某些服务在系统清单中看起来“不见了”。
速查表:你真正会用到的清单命令
| 命令 | 显示内容 |
|---|---|
systemctl list-units --type=service | 当前内存中处于活动或失败状态的服务 |
systemctl list-units --type=service --all | 所有已加载的服务,包括未激活的 |
systemctl list-units --type=service --state=running | 仅有活动进程的服务 |
systemctl --failed | 仅失败的单元——日常健康检查 |
systemctl list-unit-files --type=service | 所有已安装的服务及其开机设置 |
systemctl list-unit-files --state=enabled | 开机自动启动的单元 |
systemctl status name | 单个服务的完整信息,附带最近日志 |
systemctl is-active name | 一个词的状态,加上便于脚本使用的退出码 |
systemctl is-enabled name | 单个服务的开机配置 |
service --status-all | 以 SysV 风格列出 /etc/init.d 脚本(兼容层) |
实战工作流
1. 找出反复失败的服务
systemctl --failed
systemctl status myapp.service --no-pager -l
journalctl -xeu myapp.service
systemctl reset-failed myapp.service
先用 --failed 大范围排查,然后阅读 status 输出中的退出码和最后几行日志,再深入日志查看完整调用轨迹。根本原因修好、服务恢复后,用 reset-failed 清除过期的失败记录,这样下一次健康检查就是干净的起点。
2. 审计下次开机会启动什么
systemctl list-unit-files --type=service --state=enabled --no-legend | awk '{print $1}'
systemd-analyze blame
第一条命令会给你一份干净的自动启动清单——在加固服务器之前,或者在追查几个月前装了又忘掉的东西时非常有用。systemd-analyze blame 随后会显示上次开机时每个单元耗时多久,启动缓慢的服务会立刻凸显出来。
3. 适合脚本和监控的一行命令
systemctl is-active --quiet nginx && echo up || echo down
systemctl list-units --type=service --state=running --no-legend --plain | awk '{print $1}'
systemctl show -p ActiveState,SubState nginx
systemctl list-units --type=service -o json # systemd 246 or newer
show -p 打印的 Key=Value 对在各版本之间格式从不改变,而 JSON 输出可以直接喂给 jq。如果你发现自己每次登录都在重复同样的检查,就把它们包进一个小脚本——我们的 .sh 文件与 Shell 脚本指南正好讲了如何把这类片段变成可复用的工具。
没有 systemd?用 service --status-all 和 OpenRC
在假设 systemctl 存在之前,先确认这台机器实际运行的是什么——用命令行查看操作系统与版本只需十秒,就能告诉你是否身处一个 systemd 发行版。如果没有 systemctl,那你用的是 SysV init 或 OpenRC:
service --status-all
在 Debian 和 Ubuntu 上,它会遍历 /etc/init.d,对运行中的脚本打印 [ + ]、已停止的打印 [ - ]、没有 status 命令的打印 [ ? ]。通过兼容层,它在 systemd 发行版上仍然可用,但只能看到 init 脚本,因此在那里更应该使用 systemctl。在 Alpine 和 Gentoo 上,init 系统是 OpenRC:rc-status 列出当前运行级别的服务,rc-update show 列出各运行级别会启动什么。
以上内容都假设你有一台自己握有 root 权限的 Linux 机器,可以随意启动、弄坏并修复服务。如果你需要一台用来练手的机器——或者一台干净的机器来承载真实业务——rdp.monster 的 具备完整 root 权限的 Linux VPS 提供独享 CPU 与内存、不限流量(合理使用)、无需 KYC,并在付款确认后约 10 秒交付,让你在一分钟内就能在自己的服务器上运行 systemctl list-units。
常见问题
为什么某个服务显示 active (exited) 而不是 active (running)?
Type=oneshot(或 RemainAfterExit=yes)的服务只执行一次任务——挂载、防火墙配置、清理——然后退出。systemd 随后报告 active (exited):单元执行成功并被视为“已开启”,但没有进程常驻。只有像 nginx 或 sshd 这样的守护进程才会显示 active (running)。如果你预期是守护进程的服务却显示 exited,用 systemctl cat name.service 查看它的单元文件,看它是如何声明的。systemctl 输出中带颜色的圆点是什么意思?
systemctl status 和 systemctl list-units 中,单元名前的圆点是快速状态指示:绿色表示活动,白色表示未激活或正在停止,红色表示失败或错误状态。清单中失败的行还会以红色高亮,这让 systemctl --failed 一眼就能扫读。在颜色代码会造成干扰的脚本或日志中,加上 --plain 或把输出管道出去,这些装饰就会消失。systemctl 有和 chkconfig --list 等价的命令吗?
chkconfig --list 被 systemctl list-unit-files --type=service 取代,它会显示所有已安装的服务,以及它们是 enabled、disabled、static 还是 masked。对单个服务而言,systemctl is-enabled name 取代 chkconfig name,systemctl enable name 取代 chkconfig name on。旧命令可能仍以兼容层的形式存在,但它只覆盖遗留的 SysV 脚本。如何阻止某个服务开机启动?
sudo systemctl disable name 删除开机符号链接;加上 --now 可同时立即停止它。被 disable 的服务仍然可以手动启动,或作为其他单元的依赖被拉起。如果你希望它永远不启动,使用 sudo systemctl mask name,它会把单元链接到 /dev/null,使任何启动尝试都失败。之后可用 systemctl unmask 还原。用 systemctl is-enabled name 验证结果。Adrien Roche — 基础设施与主机托管编辑
系统工程师,拥有 10 年以上运维 Windows Server 和 Linux 集群的经验。Adrien 负责 rdp.monster 的基础设施文档,并撰写关于 RDP、VPS 托管、服务器管理、网络和隐私工具的指南。




