systemctl status 是唯一可信的服务状态检查入口,因其显示 systemd 生命周期抽象层的真实快照,涵盖 Active 状态、Main PID 健康性及关键日志,而 ps、service 等工具无法反映服务是否被正确管理或实际可用。

直接用 systemctl status 看,别信 ps 或 service --status-all ——它们只告诉你“进程在不在”,不反映服务是否被 systemd 正确管理、是否健康可用。
为什么 systemctl status 是唯一可信入口
systemd 把服务状态抽象成生命周期(loaded / active / failed / exited),而 systemctl status 显示的是这个抽象层的真实快照。比如:
-
Active: active (running)表示 unit 已启动且主进程正常;active (exited)表示它是一次性服务(如logrotate.service),执行完就退出,这属于正常 -
Main PID:后面的数字必须存在,且对应进程的State:是running,不能只是forked或exited - 最后一段日志里出现
Failed to start、Permission denied、Connection refused,哪怕显示active (running)也大概率不可用
systemctl is-active 只适合脚本判断,不适合人工诊断
它输出极简:active / inactive / unknown,但完全不告诉你为什么、卡在哪、有没有子进程崩溃。常见误判场景:
-
docker.service返回active,但实际所有容器已退出 —— 因为 systemd 认为主进程(dockerd)还在跑 -
mysql.service返回active,但连接时提示Can't connect to local MySQL server—— 得配合journalctl -u mysql --since "5 minutes ago"看真实日志 - 返回
unknown不一定代表服务没装,可能是单元文件路径不对、或被masked了(systemctl list-unit-files | grep mysql可确认)
查“正在运行的服务列表”别用 ps aux | grep
ps 匹配的是进程名,不是服务名,漏报和误报都高:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- nginx 启动后进程名是
nginx: master process,ps aux | grep nginx会把grep自己也列进来,得写成ps aux | grep '[n]ginx'才安全 -
sshd.socket这类 socket 激活服务,没连接时根本没进程,但服务单元是 ready 状态,ps完全看不到 - 像
dbus-broker.service这种核心服务,进程名和 unit 名不一致,ps查到的 PID 和systemctl status显示的 Main PID 对不上
正确做法是:systemctl list-units --type=service --state=running。如果嫌输出太多,加 | grep -v "systemd\|dbus\|polkit" 过滤掉系统底层服务。
开机自启 ≠ 当前运行,别混在一起查
systemctl is-enabled 只回答“配置上是否设为开机自启”,和当前状态无关。典型混淆场景:
-
certbot.timer是 enabled,但它本身不常驻进程,只在触发时拉起certbot.service—— 查systemctl status certbot.timer看Next: ...时间点更合理 -
systemctl list-unit-files --type=service | grep enabled能列出所有被启用的服务,但其中很多(如logrotate.service)是 oneshot 类型,查systemctl status会看到active (exited),这是对的,不是故障 - 如果某服务
is-enabled返回static,说明它不能独立启用,但可能被其他服务依赖自动激活(比如network.target)
真正要确认一个服务“现在能不能用”,永远以 systemctl status 输出中的 Active: 行 + Main PID: + 最近几行日志为准。任何绕过它的检查方式,都会在 oneshot、socket、timer 这类非传统 daemon 场景下失效。

















