最直接可靠的方式是 systemctl list-units --type=service --state=running,适用于所有主流 systemd 发行版;它准确反映 systemd 管理的运行中服务,避免 ps 或 service --status-all 的误判与遗漏。

systemctl list-units --type=service --state=running 是最直接、最可靠的方式,适用于所有主流 systemd 发行版(Ubuntu 16.04+、CentOS 7+、Debian 8+、Fedora 等)。别用 service --status-all 或裸 ps,它们要么信息混乱,要么漏掉非进程型服务(如 socket、path 触发单元)。
查正在运行的服务:用 systemctl list-units 而不是 ps
很多人习惯用 ps -ef | grep nginx,但这只找进程名匹配的进程,容易漏掉以下情况:
-
nginx可能以nginx: master process启动,grep nginx会把自身也匹配进来(需写成grep '[n]ginx'才安全) - 某些服务(如
sshd.socket)当前没处理连接,主进程未启动,但服务单元本身是“已加载”且“就绪”的——ps根本看不到它 -
dbus-broker、systemd-journald这类核心服务不走传统 daemon 模式,ps显示的 PID 和 unit 名称不一致,状态难对应
正确做法是信任 systemd 的状态抽象:
systemctl list-units --type=service --state=running
这个命令列出的是 systemd 认为“正在运行”的服务,包括 active (running)、activating (starting) 状态,不含 failed 或 exited。加 --all 可看全部状态(含 inactive),但日常排查只需 --state=running。
查某个服务是否真在跑:别只信 systemctl is-active,要看 systemctl status
systemctl is-active nginx 返回 active 并不代表服务健康——它可能卡在启动阶段、子进程崩溃但主进程还活着、或日志里满是错误却没触发失败标记。
真正要确认一个服务“可用”,必须执行:
systemctl status nginx
重点看三处:
-
Active:行末是否带(running)(而不仅是(active)) -
Main PID:是否有真实 PID,且State:是running(不是exited或dead) - 最后几行日志:是否有
Failed to start、Connection refused、Permission denied等关键词
例如 docker 服务常出现 Active: active (exited) ——这其实是 systemd 把它当成了一次性服务,实际容器进程早挂了。
查开机自启但当前没运行的服务:用 systemctl list-unit-files
有些服务(如 logrotate、certbot.timer)设计就是“按需触发”或“定时运行”,它们不会常驻进程,但你仍需要知道它们是否被启用。
这时不能看 --state=running,而要用:
systemctl list-unit-files --type=service --state=enabled
注意:--state=enabled 查的是“是否配置为开机启动”,和当前运行状态无关。返回结果中:
-
enabled:已启用,下次重启会尝试启动 -
disabled:未启用,即使手动start也不会开机自启 -
static:不能直接启用(如sshd.socket),依赖其他单元触发
别混淆 list-unit-files 和 list-units:前者查磁盘上的配置,后者查内存中的运行实例。
兼容老系统?service --status-all 问题太多,慎用
如果你在 Debian 9 或 CentOS 6 这类 SysVinit 系统上,service --status-all 确实能列出服务,但它有硬伤:
- 输出全是
[ + ]/[ - ],没告诉你哪个是真正 running,哪个只是脚本返回了 0 - 对 systemd 兼容层(如
systemd-sysv-generator生成的 wrapper)行为不可控,可能重复显示同一服务 - 根本无法识别 socket、timer、path 类单元,而这些在现代服务编排中越来越常见
如果必须支持双 init 环境,建议统一用:
if command -v systemctl >/dev/null; then systemctl list-units --type=service --state=running else service --status-all 2>/dev/null | grep '\[ + \]' fi
但更推荐直接升级到 systemd ——2026 年还在维护纯 SysV 的生产环境,通常意味着监控、日志、依赖管理都严重受限。
真正容易被忽略的点是:systemd 服务的状态语义和传统进程不等价。一个服务显示 running,只代表它的 main process PID 存在且未退出;它可能监听不了端口、连不上数据库、或拒绝新请求。所以查完列表,务必对关键服务补一句 systemctl status 看细节日志。











