应使用 systemctl list-units --type=target --state=active 查看当前真正激活的 target,它实时反映系统运行模式;multi-user.target 或 graphical.target 出现在列表中,分别等效于 runlevel 3 或 5,而 systemctl is-active 可快速验证特定 target 是否活跃。

别再用 runlevel 或 who -r 查“当前运行级别”了——它们返回的几乎总是过时或模拟值,不能反映 systemd 真实状态。
查当前真正激活的 target 用 systemctl list-units --type=target --state=active
这是唯一能反映系统“此刻正在跑什么模式”的命令。它列出所有当前 已激活 的 target 单元,不是默认值、不是历史记录、不依赖 /var/run/utmp。
-
multi-user.target在列表中 → 等效于传统 runlevel 3(纯命令行多用户) -
graphical.target在列表中 → 等效于 runlevel 5(图形界面已就绪) - 两者可能同时出现:因为
graphical.targetWants=multi-user.target,但关键看哪个是最新被isolate进来的(systemctl status输出里Active:行末的 “since” 时间最晚的那个) - 如果只看到
rescue.target或emergency.target,说明系统处于维护模式,其他服务基本没启动
systemctl is-active 判断某个 target 是否真在运行
适合脚本或快速验证,比扫列表更直接。它返回 active 或 inactive(不是数字,也不是 “N 3” 这种模糊输出)。
- 检查是否真在图形环境:
systemctl is-active graphical.target→ 返回active才算成功加载了桌面管理器 - 检查是否退到了纯命令行:
systemctl is-active multi-user.target→ 注意:这个常为active即使你开着 GUI,因为它被graphical.target依赖,所以单靠它不够,得配合上一条命令看上下文 - 返回
unknown表示该 target 文件根本不存在(比如拼错成graphical.targt)
为什么 runlevel 和 init N 不可信
它们只是 systemd 提供的兼容层,底层根本不维护“运行级别”这个状态变量。
-
runlevel读的是/var/run/utmp里残留的登录记录,不是 systemd 的实时图谱;你刚执行systemctl isolate graphical.target,它可能还显示N 3 -
init 5实际被转成systemctl isolate graphical.target,但如果display-manager.service被禁用或启动失败,GUI 就不会出现,而init命令本身却“执行成功”了 - 容器或最小化镜像里常不带
sysvinit-tools包,runlevel直接报command not found,这时你只能靠systemctl系列命令
别混淆 get-default 和当前状态
systemctl get-default 只告诉你“开机默认进哪个 target”,跟现在实际在哪毫无关系。
- 你设了
graphical.target为默认,但手动systemctl stop gdm3后,当前就是multi-user.target活跃,而get-default仍输出graphical.target - 临时切换用
systemctl isolate,它会停掉所有不在新 target 依赖图里的服务;用start只是启动目标本身,不清理旧服务,极易导致状态混乱 -
/etc/inittab在 CentOS 7+/Ubuntu 16.04+ 上完全被忽略,改它无效
真正要确认“我现在到底在哪儿”,必须组合看 systemctl list-units --type=target --state=active 和 systemctl is-active xxx.target;单独依赖任何一个命令,都容易掉进 systemd 的语义陷阱里。


















