runlevel命令输出不可信,因它仅读取/var/run/utmp中遗留记录,不反映systemd实时状态;真实运行目标须用systemctl list-units --type=target --state=active查看。

现在用 runlevel 看到的数字基本没参考价值,真实状态得查 systemctl list-units --type=target --state=active。
为什么 runlevel 命令输出不可信
它只是读 /var/run/utmp 里遗留的登录记录,不参与 systemd 运行时管理;比如你刚用 systemctl isolate graphical.target 切到图形界面,runlevel 可能还显示 N 3(N 表示 previous 未定义),因为它压根没更新这个字段。
常见错误现象:
-
runlevel显示3,但桌面正常运行——说明系统实际在graphical.target,runlevel只是映射了历史习惯(3→multi-user.target) -
telinit 5能执行成功,但没启动 GUI——因为 systemd 把它转成了isolate graphical.target,但若display-manager.service被禁用或失败,就不会真起图形会话
怎么查当前真正激活的 target
用 systemctl 直接看活跃的 target 单元,这是唯一权威方式:
- 列出所有已激活的 target:
systemctl list-units --type=target --state=active - 只看默认启动目标(开机进哪个):
systemctl get-default - 确认是否真的在图形环境:
systemctl is-active graphical.target(返回active才算)
注意:multi-user.target 和 graphical.target 可以同时 active——因为后者 Wants= 前者,但关键看哪个是 isolate 的目标。用 systemctl status 看 Active: 行末尾的 “since” 时间,最新被 isolate 的那个才是当前主 target。
切换 target 不要用 systemctl start
start 只启动目标本身,不清理不属于它的服务;isolate 才是“切换”的语义,会停掉所有不在新 target 依赖图里的服务。
- 临时切到纯命令行(关 GUI):
systemctl isolate multi-user.target - 临时切回图形界面:
systemctl isolate graphical.target - 如果卡住不动,大概率是某个 service 没声明
StopWhenUnneeded=yes或Conflicts=,导致 systemd 不敢停它 -
isolate不改默认启动目标,重启后仍按get-default结果加载
设默认启动 target 别碰 /etc/inittab
CentOS 7+/Ubuntu 16.04+ 完全忽略 /etc/inittab;改它毫无作用。
- 设默认多用户(无 GUI):
systemctl set-default multi-user.target - 设默认图形界面:
systemctl set-default graphical.target - 执行后会自动创建符号链接
/etc/systemd/system/default.target → /lib/systemd/system/graphical.target - 老脚本里写死的
init 3会被重定向,但不会触发/etc/rc.local等 SysV 遗留逻辑
target 文件本身不执行代码,只是依赖集合;真正差异藏在 Wants=、Conflicts= 和 After= 字段里——比如 graphical.target 的 Wants=display-manager.service,而 multi-user.target 的 Conflicts=display-manager.service,这才是隔离干净的关键。











