systemctl list-units --type=service --state=running是最准确命令,它直接读取systemd运行时状态,避免ps漏掉子进程或grep自身、service--status-all在systemd系统上模拟失真、以及无法识别socket/timer等按需服务的问题。

systemctl list-units --type=service --state=running 是最准的命令,它直接读取 systemd 的运行时状态,不是靠猜进程名或端口。
为什么不用 ps 或 service --status-all?
这两个命令看起来快,但实际容易误判:
- ps -ef | grep nginx 会漏掉 nginx: worker process 这类子进程,还可能把 grep 自身也列进来(得写成 grep '[n]ginx' 才安全)
- service --status-all 在 systemd 系统上只是模拟 SysV 行为,很多服务根本不走这个路径,比如 sshd.socket、dbus-broker,返回结果全是“[ ? ]”或空白
- 某些服务(如 logrotate、certbot.timer)压根不常驻进程,ps 根本看不到,但它们确实是“已启用且按需触发”的有效服务
systemctl list-units 的关键参数组合
日常排查只用这一条就够了:systemctl list-units --type=service --state=running
但它有几个容易被忽略的变体:
- 加 --all 会显示 inactive、failed、exited 状态的服务,信息量爆炸,一般不用
- 不加 --state=running 默认只显示 loaded + active 的,但有些 unit 处于 activating 状态(正在启动),它会被包含;加了才严格过滤出真正 running 的
- 如果只想看服务名(方便管道后续处理),加 --plain --no-legend:systemctl list-units --type=service --state=running --plain --no-legend | cut -d' ' -f1
查某个服务是否真在干活,不能只信 systemctl is-active
systemctl is-active nginx 返回 active 并不等于 nginx 正在响应请求:
- 可能卡在 reload 阶段,主进程没退出但配置没生效
- 可能 worker 进程全崩了,master 还活着(systemctl status nginx 里 Main PID 对应的进程实际 State: exited)
- 日志里有 bind() to 0.0.0.0:80 failed (98: Address already in use) 这类错误,但 unit 状态仍是 active
所以必须看:
- Active: 行末括号里是不是 (running)(不是 (exited) 或 (activating))
- Main PID: 后面的数字是否真实存在(kill -0 <pid></pid> 能成功)
- 最后三行日志有没有明显失败关键词
非 systemd 系统(如旧版 CentOS 6)怎么办?
确认是 SysV init 后,老老实实用:service --status-all 2>/dev/null | grep 'is running'
注意:
- 输出里带 [ + ] 的不一定真在跑,有些脚本只检查 pid 文件是否存在,而进程早死了
- /etc/init.d/ 下有脚本 ≠ 服务已启用,还得看 chkconfig --list 或 ls /etc/rc*.d/
- 没有 systemd 就别硬套 systemctl,会报 Failed to connect to bus
真正要确认一个服务“可用”,得结合状态、进程、端口、日志四层验证。只查一层,十次里有三次会漏掉问题。











