RDP Monster

systemctl 列出服务:Linux 服务清单的全部方法

systemctl 列出服务:Linux 服务清单的全部方法

必须掌握的一条命令: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 statusstartstop 的名称。
  • LOAD —— 单元文件是否被正确解析:loadednot-foundbad-settingerrormasked
  • ACTIVE —— 高层状态:activeinactiveactivatingdeactivatingfailed
  • SUB —— 与单元类型相关的底层状态:一个服务可以是 runningexiteddead 等。
  • 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 会去掉行首的圆点符号,这样列的位置对 awkcut 来说更稳定。要按名称搜索,可以管道给 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 PRESETPRESET),显示发行版的默认设置是什么。需要避开的陷阱是: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 可以隐藏输出,只保留退出码。

上面所有列出类命令都可以用非特权用户执行。真正管理服务——startstopenabledisable——需要 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)?

那是一个成功执行完毕的 oneshot 服务——不是错误。
Type=oneshot(或 RemainAfterExit=yes)的服务只执行一次任务——挂载、防火墙配置、清理——然后退出。systemd 随后报告 active (exited):单元执行成功并被视为“已开启”,但没有进程常驻。只有像 nginx 或 sshd 这样的守护进程才会显示 active (running)。如果你预期是守护进程的服务却显示 exited,用 systemctl cat name.service 查看它的单元文件,看它是如何声明的。

systemctl 输出中带颜色的圆点是什么意思?

绿色表示活动,白色表示未激活,红色表示失败或出错。
systemctl statussystemctl list-units 中,单元名前的圆点是快速状态指示:绿色表示活动,白色表示未激活或正在停止,红色表示失败或错误状态。清单中失败的行还会以红色高亮,这让 systemctl --failed 一眼就能扫读。在颜色代码会造成干扰的脚本或日志中,加上 --plain 或把输出管道出去,这些装饰就会消失。

systemctl 有和 chkconfig --list 等价的命令吗?

有——systemctl list-unit-files --type=service 取代了 chkconfig --list。
在 RHEL 与 CentOS 7 及更高版本上,chkconfig --listsystemctl list-unit-files --type=service 取代,它会显示所有已安装的服务,以及它们是 enableddisabledstatic 还是 masked。对单个服务而言,systemctl is-enabled name 取代 chkconfig namesystemctl enable name 取代 chkconfig name on。旧命令可能仍以兼容层的形式存在,但它只覆盖遗留的 SysV 脚本。

如何阻止某个服务开机启动?

用 systemctl disable 把它从开机项中移除,或用 mask 彻底屏蔽。
运行 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 托管、服务器管理、网络和隐私工具的指南。

注册加入我们的分销商计划

您的信息

如有任何疑问, contact us by clicking here !
姓名(必填)
请填写您的邮箱地址,您必须拥有以下网站的账号: manager.rdp.monster !

您的公司

如果您有网站,请填写网址
请简要说明您打算如何向客户销售服务,例如在论坛上与人交流推广。

我们使用 cookie !

我们使用 cookie 来改善您的浏览体验、提供个性化的广告或内容,并分析我们的流量。点击「接受」即表示您同意我们使用 cookie。