poweroff 命令详解与参数实测(Ubuntu 22.04)
基于 Ubuntu 22.04(systemd 249)环境对 poweroff 命令的逐参数实测手册:直接执行优雅关机断电(journal 判定行 Reached target System Power Off)、--halt 切换挂起、--reboot 切换重启(强制路径动词 Rebooting.)、-p 默认动作的显式写法、-f 强制 Powering off.、-w 实测不写 wtmp、-d 拦不住优雅留痕、--no-wall,以及 who -b 分钟级分辨率在同分钟两次停机时的盲区、非 root 三连报错与 [ARG] 位置参数拒绝行为,所有破坏性命令均真实执行并以 last -x 与 journal 双重留痕闭环验证。
poweroff 命令详解与参数实测(Ubuntu 22.04)
目标:全面掌握 poweroff 的每一个参数与用法——无参数直接执行(优雅关机断电,journal 判定行为
Finished System Power Off.+Reached target System Power Off.)、--halt切换为挂起动作、--reboot切换为重启动作、-p默认动作的显式写法、-f强制执行(回显Powering off.)、-w的实测表现(未产生任何 wtmp 记录)、-d拦不住优雅路径留痕、--no-wall,以及帮助里带[ARG]但位置参数被Too many arguments.拒绝、非 root 三连报错、who -b分钟级分辨率在同分钟两次停机时的盲区,全部命令与回显已在 Ubuntu 22.04(systemd 249)环境实测通过,其中停机类参数均真实执行并记录了主机停止前后的 wtmp 与 journal 双重证据。
一、环境信息
本文所有命令均在以下环境实测,回显逐字照抄:
- 操作系统:Ubuntu 22.04.5 LTS(
PRETTY_NAME="Ubuntu 22.04.5 LTS") - 内核:6.8.0-138-generic,x86_64 架构
- init 系统:systemd 249 (249.11-0ubuntu3.23),
systemctl is-system-running实测返回running - poweroff 所属软件包:systemd 249.11-0ubuntu3.23
- poweroff 真实身份:
/usr/sbin/poweroff -> /bin/systemctl符号链接(3.1 节实测确认) - 系统时区:UTC(
date输出带 UTC 后缀),下文回显中的时间均为系统本地时间 - 执行身份:root
- 演示目录:
/root/demo/poweroff/
💡 说明:poweroff 每次真实执行都会让主机停止运行,本文所有破坏性命令都真实执行过,并以停机前后的 wtmp 留痕(
last -x输出)与 journal 优雅停机序列双重证据闭环,因此部分小节的回显是「执行命令 → 主机停止 → 重新启动后查看日志」的完整闭环,读者在自己的测试机上复现时请提前保存工作内容。
二、命令概览
2.1 语法与测试数据
poweroff 用于关机并请求断电。语法(来自实测 poweroff --help 首行):
poweroff [OPTIONS...] [ARG]
帮助里有 [ARG] 位置参数——但实测任何位置参数都会被 Too many arguments. 拒绝(3.12 节),与 reboot 的「静默接受一个」(reboot 篇 3.12 节)不同。不写任何选项时,默认动作为关机断电。本文测试数据约定:破坏性命令均单独执行、前后用 last -x 留痕对账;非破坏性命令(-w 组合、非法参数、非 root 试探)在确认系统 running 状态下执行。
💡 技术拓展:poweroff 名义下的动作切换——
命令 默认动作 加 --halt加 --rebootpoweroff 断电(Reached target System Power Off) 挂起(Starting System Halt...) 重启(强制路径动词 Rebooting.) 与 halt 不同,poweroff 名义下「切走」默认动作要靠长选项;短选项
-p在这里只是默认动作的显式写法(3.4 节)。三种结局的 journal 判定行详见 3.3/3.5 节与 3.13 节动作切换矩阵。
2.2 --help 全量输出(逐行照抄)
先看完整帮助,是逐参数实测的地图。以下为 poweroff --help 的完整实测输出:
$ poweroff --help
poweroff [OPTIONS...] [ARG]
Power off the system.
Options:
--help Show this help
--halt Halt the machine
-p --poweroff Switch off the machine
--reboot Reboot the machine
-f --force Force immediate halt/power-off/reboot
-w --wtmp-only Don't halt/power-off/reboot, just write wtmp record
-d --no-wtmp Don't write wtmp record
--no-wall Don't send wall message before halt/power-off/reboot
See the halt(8) man page for details.
关键差异解读:
- 首行语法带
[ARG],但实测位置参数会被Too many arguments.拒绝(3.12 节)——帮助文本与行为不一致的又一个实例; - 描述行是
Power off the system.(reboot 是 "Reboot the system.",halt 是 "Halt the system."),三个命令共用同一份选项表、同一份 halt(8) 手册; -p --poweroff的描述是 "Switch off the machine"——在 poweroff 名义下它与默认动作等价(3.4 节)。
2.3 版本信息
Ubuntu 22.04 的 poweroff 属于 systemd 软件包,实测版本信息如下:
$ systemctl --version
systemd 249 (249.11-0ubuntu3.23)
+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY -P11KIT -QRENCODE +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified
$ dpkg -l systemd | tail -1
ii systemd 249.11-0ubuntu3.23 amd64 system and service manager
systemctl --version 的第一行就是 poweroff 实际运行的版本(249.11-0ubuntu3.23)。本文各参数行为均为该版本实测结论,升级 systemd 后请以现场实测为准。
三、参数逐项实测
3.1 先确认身份:poweroff 是 systemctl 的符号链接
systemd 时代的 poweroff 不是独立二进制,而是 systemctl 的符号链接。systemctl 运行时按 argv[0](程序被调用的名字)判定要执行的动作:
ls -l /usr/sbin/shutdown /usr/sbin/reboot /usr/sbin/halt /usr/sbin/poweroff
实测回显:
$ ls -l /usr/sbin/shutdown /usr/sbin/reboot /usr/sbin/halt /usr/sbin/poweroff
lrwxrwxrwx 1 root root 14 Oct 12 07:44 /usr/sbin/halt -> /bin/systemctl
lrwxrwxrwx 1 root root 14 Oct 12 07:44 /usr/sbin/poweroff -> /bin/systemctl
lrwxrwxrwx 1 root root 14 Oct 12 07:44 /usr/sbin/reboot -> /bin/systemctl
lrwxrwxrwx 1 root root 14 Oct 12 07:44 /usr/sbin/shutdown -> /bin/systemctl
💡 要点:
- 四个命令全部指向
/bin/systemctl,本质上是同一套代码的不同入口;因此 2.2 节poweroff --help显示的是 poweroff 专属的短帮助——systemctl 按 argv[0] 识别了身份; dpkg -S /usr/sbin/poweroff可确认归属(输出systemd: /usr/sbin/poweroff),排障时可用于区分是 systemd 包还是 SysV 兼容包提供的同名命令。
3.2 无参数直接执行:优雅关机断电(真实执行)
poweroff 不带参数走完整的优雅停机流程,最终执行断电动作(停止系统并请求切断电源)。命令本身没有输出,回车后系统随即开始停机:
poweroff
执行后主机停止运行。在无可控电源域的运行环境里,系统停止后会被外部重新拉起(效果等同重启,但执行路径可由 journal 严格区分)。恢复后用 last -x 查看留痕(节选头部):
$ last -x | head -6
runlevel (to lvl 5) 6.8.0-138-generi Fri Oct 16 09:54 still running
reboot system boot 6.8.0-138-generi Fri Oct 16 09:54 still running
shutdown system down 6.8.0-138-generi Fri Oct 16 09:54 - 09:54 (00:00)
runlevel (to lvl 5) 6.8.0-138-generi Fri Oct 16 09:54 - 09:54 (00:00)
reboot system boot 6.8.0-138-generi Fri Oct 16 09:54 - 09:54 (00:00)
shutdown system down 6.8.0-138-generi Fri Oct 16 09:54 - 09:54 (00:00)
journal 中本次优雅停机的收尾序列(节选):
Oct 16 09:54:48 b8307d66e0c6 systemd[1]: Stopped Remount Root and Kernel File Systems.
Oct 16 09:54:48 b8307d66e0c6 systemd[1]: Reached target System Shutdown.
Oct 16 09:54:48 b8307d66e0c6 systemd[1]: Reached target Late Shutdown Services.
Oct 16 09:54:48 b8307d66e0c6 systemd[1]: systemd-poweroff.service: Deactivated successfully.
Oct 16 09:54:48 b8307d66e0c6 systemd[1]: Finished System Power Off.
Oct 16 09:54:48 b8307d66e0c6 systemd[1]: Reached target System Power Off.
Oct 16 09:54:48 b8307d66e0c6 systemd[1]: Shutting down.
Oct 16 09:54:48 b8307d66e0c6 systemd-journald[23]: Journal stopped
💡 要点:
- 判定行是
systemd-poweroff.service: Deactivated successfully.→Finished System Power Off.→Reached target System Power Off.——断电动作有完整的收尾三连,与 halt 的Starting System Halt...(只有 Starting、无 Finished 行,见 halt 篇 3.2 节)在 journal 中可严格区分; - wtmp 层面与优雅挂起/重启长得一样(有
shutdown system down结束标记 + 新 boot 记录)——区分「这次停机到底是什么动作」必须看 journal 判定行(Q3 有速查表); - 优雅路径下 wtmp 的 down 记录由 systemd-update-utmp 服务写入(journal 序列中的
Stopped Record System Boot/Shutdown in UTMP.),这解释了 3.8 节-d为什么拦不住它。
3.3 --halt:切换为挂起动作(真实执行)
--halt 把 poweroff 的动作从断电切换为挂起。真实执行:
poweroff --halt
journal 中的结局判定行(时间戳 10:07:25 对应本次 poweroff --halt):
Oct 16 10:07:25 b8307d66e0c6 systemd[1]: Starting System Halt...
Starting System Halt...(挂起收尾单元 systemd-halt.service 启动)证明动作已从断电切换为挂起。配合 -f 强制路径的动词回显交叉确认:
$ poweroff --halt -f
Halting.
💡 要点:
poweroff --halt的结局与 halt 直接执行完全一致(journal 同为Starting System Halt...),说明动作由解析层决定、与入口名义无关;-f组合打印的动词是Halting.而不是Powering off.——强制路径的动词按解析后的动作打印,是验证动作切换最直接的手段;- 想表达「停住但不断电」,写
halt或poweroff --halt都行,但前者名字与动作一致、可读性更好。
3.4 -p:默认动作的显式写法
-p --poweroff 在 poweroff 名义下只是默认动作(断电)的显式形式。用 -f 组合的动词回显验证(-p 不改变解析结果,动词与默认动作一致):
$ poweroff -p -f
Powering off.
💡 要点:
poweroff -p与poweroff是同一动作的两种写法,journal 结局同为Reached target System Power Off.(3.2 节);- 与 halt 名义下
-p真实切换动作(halt 篇 3.4 节)不同——同一个-p,在 halt 是「切换器」、在 poweroff 是「回声」; - 与 reboot 名义下
-p被忽略(reboot 篇 3.5 节实测reboot -p仍重启)也不同——同一家族、同一参数、三种命运,完整地图见 3.13 节动作切换矩阵。
3.5 --reboot:切换为重启动作
--reboot 把 poweroff 的动作切换为重启。本节用 -f 强制路径验证动作切换(强制路径的动词回显由 systemctl 按解析后动作打印,是最直接的证据):
$ poweroff --reboot -f
Rebooting.
用 -w 组合做非破坏性的解析验证(-w 的实测行为见 3.7 节:不会停机、也不写记录):
$ systemctl is-system-running
running
$ poweroff --reboot -w
$ echo "退出码=$?"
poweroff --reboot -w 退出码=0
$ systemctl is-system-running
running
💡 要点:
- 动词
Rebooting.证明--reboot在 poweroff 名义下真实生效,动作已切换为重启; - 长选项
--reboot无条件生效(对照短选项-p的名义依赖),这与 reboot --halt(reboot 篇 3.4 节)、halt --reboot(halt 篇 3.5 节)的实测结论一致; - 优雅路径的 journal 证据见
halt --reboot(halt 篇 3.5 节,Reached target System Reboot.)——两者共用同一份动作解析代码,解析结果相同;本节以强制路径动词 +-w解析验证双重留痕。
3.6 -f:强制立即断电(跳过优雅停机)
-f --force 跳过 systemd 的优雅停机流程,由 systemctl 自己直接执行停机系统调用,先打印一行动词再执行:
$ poweroff -f
Powering off.
执行后主机立即断电,不等待服务停止。真实执行前后用 last -x 对账(破坏前头 3 行 → 执行 → 恢复后头 5 行):
--- 破坏前 last -x 头 3 行 ---
runlevel (to lvl 5) 6.8.0-138-generi Fri Oct 16 10:08 still running
reboot system boot 6.8.0-138-generi Fri Oct 16 10:08 still running
shutdown system down 6.8.0-138-generi Fri Oct 16 10:07 - 10:08 (00:00)
--- 执行 poweroff -f ---
Powering off.
--- 恢复后 last -x 头 5 行 ---
runlevel (to lvl 5) 6.8.0-138-generi Fri Oct 16 10:08 still running
reboot system boot 6.8.0-138-generi Fri Oct 16 10:08 still running
runlevel (to lvl 5) 6.8.0-138-generi Fri Oct 16 10:08 - 10:08 (00:00)
reboot system boot 6.8.0-138-generi Fri Oct 16 10:08 still running
shutdown system down 6.8.0-138-generi Fri Oct 16 10:07 - 10:08 (00:00)
💡 要点:
Powering off.由 systemctl 自己打印(强制路径不再经过 systemd 停机序列),同族动词还有Rebooting.(reboot -f)与Halting.(halt -f / poweroff --halt -f),三个动词正好对应三种动作,是验证动作解析结果的直接手段;- 恢复后头部没有本次停机的
shutdown system down记录(最新的 down 记录 10:07 - 10:08 属于上一个 boot),且第 4 行旧 boot 的reboot system boot 10:08停留在still running状态——这就是「僵尸 boot 记录」:强制路径不写 down 标记,旧 boot 记录永远闭合不上(与 reboot -f 行为一致,reboot 篇 3.6 节); -f的代价清单与 reboot 篇 3.6 节相同:服务无优雅关闭、文件系统缓存未回写、wtmp 无 down 记录且留僵尸 boot 记录。
3.7 -w:声称「只写 wtmp」,实测什么都没写(真实踩坑#1)
帮助文本声称 -w --wtmp-only 是 "Don't halt/power-off/reboot, just write wtmp record"。前半句实测成立(确实不停机),后半句实测不成立:
$ last -x reboot
reboot system boot 6.8.0-138-generi Thu Oct 15 18:07 still running
wtmp begins Thu Oct 15 18:07:39 2026
$ poweroff -w
$ echo "退出码=$?"
退出码=0
$ last -x reboot
reboot system boot 6.8.0-138-generi Thu Oct 15 18:07 still running
wtmp begins Thu Oct 15 18:07:39 2026
$ systemctl is-system-running
running
md5 直接对比文件字节(另一次验证):
$ md5sum /var/log/wtmp
46978aa93d26974e9218682781c94ae4 /var/log/wtmp
$ poweroff -w
$ md5sum /var/log/wtmp
46978aa93d26974e9218682781c94ae4 /var/log/wtmp
💡 要点:
- 在 systemd 249 上,
poweroff -w退出码 0、无输出、系统保持运行,但/var/log/wtmp一个字节都没变——reboot -w与halt -w同样实测无变化(md5 完全一致),三个名义行为相同; -w因此成为家族里唯一绝对非破坏的参数:即使与-f组合系统也不会停止,可当参数解析探针用;- 老教程中「-w 用于构造 wtmp 记录」的说法在本版本上不成立,写运维文档时不要照抄。
3.8 -d:声称「不写 wtmp」,优雅路径拦不住(真实踩坑#2)
帮助文本声称 -d --no-wtmp 是 "Don't write wtmp record"。真实执行 poweroff -d 后恢复,查看头部:
$ last -x | head -5
runlevel (to lvl 5) 6.8.0-138-generi Fri Oct 16 10:04 still running
reboot system boot 6.8.0-138-generi Fri Oct 16 10:04 still running
shutdown system down 6.8.0-138-generi Fri Oct 16 10:04 - 10:04 (00:00)
runlevel (to lvl 5) 6.8.0-138-generi Fri Oct 16 09:57 - 10:04 (00:06)
reboot system boot 6.8.0-138-generi Fri Oct 16 09:57 - 10:04 (00:06)
第 3 行的 shutdown system down 10:04 - 10:04 正是本次 poweroff -d 结束的那个 boot 的留痕——-d 没有拦住它。journal 同时确认动作本身正常(时间戳 10:04:11 对应本次执行):
Oct 16 10:04:11 b8307d66e0c6 systemd[1]: systemd-poweroff.service: Deactivated successfully.
Oct 16 10:04:11 b8307d66e0c6 systemd[1]: Finished System Power Off.
Oct 16 10:04:11 b8307d66e0c6 systemd[1]: Reached target System Power Off.
💡 要点:
- 原因同 reboot 篇 3.8 节:优雅路径的 wtmp 留痕由停机序列中的 systemd-update-utmp 服务写入,
-d是 systemctl 进程自己的开关,管不到停机序列里的写入者; -d对-f强制路径也无效——但强制路径本来就什么都不写(3.6 节),无处可拦;- 结论:想「悄悄停机、不留 down 记录」在本版本上做不到,
last -x审计记录是可信的。
3.9 --no-wall:不发广播消息(优雅路径实测)
--no-wall 只控制停机前的 wall 广播,不影响停机动作本身。真实执行:
poweroff --no-wall
journal 确认动作正常完成(时间戳 10:07:57 对应本次执行):
Oct 16 10:07:57 b8307d66e0c6 systemd[1]: systemd-poweroff.service: Deactivated successfully.
Oct 16 10:07:57 b8307d66e0c6 systemd[1]: Finished System Power Off.
Oct 16 10:07:57 b8307d66e0c6 systemd[1]: Reached target System Power Off.
💡 要点:
- poweroff 没有接受自定义消息正文的位置参数(2.1/3.12 节,任何位置参数都会被拒绝),系统广播的固定文案由 logind 在调度时生成,
--no-wall的作用就是连这条固定广播也省去; - 本实测环境无交互登录会话,广播文案差异不作为本文的实测结论;在多用户生产机上,摘掉广播等于用户毫无预警被踢线,维护窗口外请勿使用;
- 需要自定义广播内容的关机,用
shutdown -P +m '消息'(shutdown 篇 3.9 节已实测 wall 广播机制)。
3.10 非 root 执行:logind 拒绝 + 报错三连
普通用户执行 poweroff 会被拒绝。实测(演示用户 pwuser 通过 useradd -m -s /bin/bash pwuser 创建):
$ su - pwuser -c "poweroff"
Failed to power off system via logind: Access denied
Failed to open initctl fifo: Permission denied
Failed to talk to init daemon.
$ echo "退出码=$?"
退出码=1
reboot 与 halt 在非 root 下的报错形态完全相同,仅第一行动词不同(Failed to reboot system via logind: Access denied / Failed to halt system via logind: Access denied),退出码同为 1。测试后清理演示用户(userdel -r pwuser)。
💡 要点:
- 三连报错暴露了 systemctl 的降级尝试链:先问 systemd-logind(被 polkit 拒绝)→ 再尝试 SysV 兼容的
/run/initctlfifo → 最后直接和 init daemon 通话——三层全被拒后才放弃; - 与 shutdown 的非 root 报错形态不同(shutdown 报
Failed to call ScheduleShutdown in logind, no action will be taken: Access denied,走「调度」方法)——poweroff 走「立即执行」方法; - 授权普通用户关机的正道是 polkit 规则或
sudo poweroff。
3.11 非法选项:unrecognized option 退出码 1
$ poweroff --bogus
poweroff: unrecognized option '--bogus'
$ echo "退出码=$?"
退出码=1
💡 要点:报错前缀是 poweroff:(argv[0] 名义),退出码 1。结合 3.10 节,非 root 与参数错误都是退出码 1,脚本里要区分二者只能看报错文本。
3.12 位置参数:帮助里有 [ARG],实测被 Too many arguments. 拒绝
poweroff 的帮助语法里有 [ARG],但实测任何位置参数都会被拒绝。用 -w 组合保证非破坏:
$ poweroff -w baz
Too many arguments.
$ echo "ARG baz 退出码=$?"
ARG baz 退出码=1
对照 reboot 名义下 reboot -w foo 静默接受(退出码 0,见 reboot 篇 3.12 节),halt 同样拒绝(halt -w bar → Too many arguments.,halt 篇 3.12 节)。
💡 要点:
- 三个命令的帮助首行写法不同(halt 无
[ARG]、reboot/poweroff 有[ARG]),实测接受度却与帮助不完全对应——reboot 独静默接受一个,halt/poweroff 都拒绝;poweroff 是「帮助写了 [ARG]、行为却拒绝」的那一个; - 这个差异是「同一套代码、按 argv[0] 分派后各自再校验」的产物,遇到「帮助相同、行为不同」的情况,以实测为准。
3.13 技术拓展:四命令对比与动作切换矩阵
reboot/halt/poweroff/shutdown 四命令的完整实测对照(本表所有结论均出自本环境实测,细节见各篇对应小节):
| 维度 | shutdown | reboot | halt | poweroff |
|---|---|---|---|---|
| 帮助语法 | [OPTIONS...] [TIME] [WALL...] | [OPTIONS...] [ARG] | [OPTIONS...] | [OPTIONS...] [ARG] |
| 默认动作 | 关机断电(延时 1 分钟) | 重启 | 挂起 | 关机断电 |
| 延时/定时 | ✓ now/+m/hh:mm | ✗ | ✗ | ✗ |
| 自定义广播消息 | ✓ [WALL...] | ✗ | ✗ | ✗ |
-c 取消计划 | ✓ | ✗ | ✗ | ✗ |
-k 假广播 | ✓ | ✗ | ✗ | ✗ |
-f 强制动词回显 | ✗(无此参数) | Rebooting. | Halting. | Powering off. |
-w 只写 wtmp | ✗(无此参数) | 有参数,实测未写任何记录 | 同左 | 同左 |
-d 不写 wtmp | ✗(无此参数) | 有参数,优雅路径拦不住 | 同左 | 同左 |
--no-wall | ✓ | ✓ | ✓ | ✓ |
| 非 root 报错第一行 | Failed to call ScheduleShutdown in logind... | Failed to reboot system via logind... | Failed to halt system via logind... | Failed to power off system via logind... |
| 优雅路径 journal 结局 | Reached target System Power Off.(默认)/Reached target System Reboot.(-r)/Starting System Halt...(-H) | Reached target System Reboot. | Starting System Halt... | Reached target System Power Off. |
动作切换矩阵(名义 × 选项,括号内为 journal/动词回显证据):
| 名义 \ 选项 | (无选项) | --halt | -p | --reboot |
|---|---|---|---|---|
reboot | 重启(Reached target System Reboot) | 挂起(Starting System Halt...) | 仍重启(-p 被忽略,Rebooting.) | 重启(-w 组合解析验证 rc=0) |
halt | 挂起(Starting System Halt...) | 挂起(同默认) | 断电(Reached target System Power Off) | 重启(Reached target System Reboot) |
poweroff | 断电(Reached target System Power Off) | 挂起(Starting System Halt...) | 断电(同默认,Powering off.) | 重启(强制路径动词 Rebooting.) |
💡 要点:
- poweroff 是四命令中「名字与默认动作严格对应」的一个:不带参数即断电,无需任何参数修正语义;
- 长选项
--halt/--reboot无条件生效;短选项-p只在 halt/poweroff 名义下有意义——在 halt 是切换器、在 poweroff 是回声、在 reboot 被忽略; - 生产建议一句话版:定时/带广播/可取消的关机用
shutdown -P,立即关机用poweroff,重启用reboot,halt留给真正需要「停在那里」的物理机场景。
四、实战示例
4.1 关机后用 wtmp 对账(审计闭环)
关机维护后第一时间对账。关机前先记下当前 boot 时间:
who -b
poweroff
实测回显(关机前,who -b 显示当时 boot 时间为 11:14):
system boot Oct 16 11:14
--- 执行 poweroff ---
恢复后执行:
who -b
last -x | head -5
last -x shutdown | head -2
实测回显:
$ who -b
system boot Oct 16 11:14
$ last -x | head -5
runlevel (to lvl 5) 6.8.0-138-generi Fri Oct 16 11:14 still running
reboot system boot 6.8.0-138-generi Fri Oct 16 11:14 still running
shutdown system down 6.8.0-138-generi Fri Oct 16 11:14 - 11:14 (00:00)
runlevel (to lvl 5) 6.8.0-138-generi Fri Oct 16 11:14 - 11:14 (00:00)
reboot system boot 6.8.0-138-generi Fri Oct 16 11:14 - 11:14 (00:00)
$ last -x shutdown | head -2
shutdown system down 6.8.0-138-generi Fri Oct 16 11:14 - 11:14 (00:00)
shutdown system down 6.8.0-138-generi Fri Oct 16 11:14 - 11:14 (00:00)
解读:
- 两次
who -b显示的 boot 时间都是 11:14——本次poweroff与上一次停机落在同一分钟,who -b只有分钟级分辨率,看不出变化(这是它的盲区,Q5 详述); last -x里旧 boot 记录闭合为11:14 - 11:14 (00:00)、新 boot 记录still running——本次 poweroff 的停机与重新启动链路完整;last -x shutdown头两条都是11:14 - 11:14:第一条是本次优雅关机写下的 down 记录(走优雅路径才有,强制路径不会产生,见 3.6 节),第二条是紧邻的上一次停机留下的——同一分钟内的两次停机在 wtmp 里无法按时间区分;- 区分手段在 journal:本次执行对应的收尾判定行是
Finished System Power Off.+Reached target System Power Off.(断电,11:14:50 窗口),上一次是Starting System Halt...(挂起,11:14:44 窗口)。
4.2 立即关机的三种写法:poweroff、shutdown -P now、halt -p
三者在本环境的 journal 结局相同(都是 Reached target System Power Off.)。选择建议:立即关机直接 poweroff(名字即意图,不依赖参数组合的记忆);需要延时、广播消息或可取消时用 shutdown -P +m(shutdown 篇已实测全链路);halt -p 是 SysV 时代的习惯写法,实测同样有效(halt 篇 3.4 节)但语义要靠参数拼接,团队协作脚本里不如 poweroff 直白。
4.3 系统无响应时的强制断电
优雅路径无响应时,poweroff -f 是最后手段:
$ poweroff -f
Powering off.
执行后主机立即断电。代价清单见 3.6 节:服务无优雅关闭、wtmp 无 down 记录且旧 boot 记录留僵尸态。恢复后建议立即检查文件系统日志与 fsck 计划。
4.4 脚本中安全关机的前置检查
#!/bin/bash
# 前置检查 1:系统处于可关机状态
state=$(systemctl is-system-running)
if [ "$state" != "running" ]; then
echo "系统状态异常($state),拒绝关机" >&2
exit 1
fi
# 前置检查 2:权限试探(借用 -w 组合,非破坏)
poweroff -w
if [ $? -ne 0 ]; then
echo "关机权限不足(非 root 或 polkit 拒绝)" >&2
exit 1
fi
poweroff
实测依据:systemctl is-system-running 在本环境返回 running(一、环境信息);poweroff -w 非破坏(3.7 节)且权限不足/参数错误均为退出码 1(3.10/3.11 节)。
五、注意事项与常见问题
Q1:poweroff 与 halt 到底差在哪?
差在最终动作:poweroff 请求断电(journal 收尾 Reached target System Power Off.),halt 只停住不断电(journal 收尾 Starting System Halt...,halt 篇 3.2 节)。物理机上 halt 后主机保持通电、停在内核停止态,需要现场按电源键;poweroff 后电源直接切断。在本实测环境这类无可控电源域的托管运行环境里,两者停止后都被外部重新拉起、最终表现接近,但 journal 判定行能严格证明走的是哪条路径(Q3 速查表)。
Q2:poweroff 与 shutdown -P now / shutdown -h now 有什么区别?
结局完全相同:journal 都收尾于 Reached target System Power Off.。区别在入口能力:shutdown 支持 [TIME] 延时、自定义广播消息、-c 取消、会写 /run/nologin 拦截后续登录;poweroff 一概没有,回车即停。另外帮助文本注明 shutdown -h 默认等价于 --poweroff(除非被 --halt 覆盖),所以 shutdown -h now 与 shutdown -P now 结局一致。
Q3:wtmp 里 poweroff 的 down 记录和 reboot/halt 长得一模一样,怎么区分动作?
wtmp 只记录「发生过优雅停机」,不记录动作类型;区分动作必须看 journal 收尾判定行:
| journal 收尾行 | 结论 |
|---|---|
Finished System Reboot. + Reached target System Reboot. | 优雅重启 |
Starting System Halt...(无 Finished 行) | 优雅挂起 |
Finished System Power Off. + Reached target System Power Off. | 优雅断电 |
只有 Shutting down. 前无上述任何行 | 强制路径(-f),无优雅序列 |
Q4:为什么 poweroff -w 没有生成 wtmp 记录?
实测(last -x 前后对比 + /var/log/wtmp md5 前后一致)确认 249 上该参数什么都没写。-w 的价值仅剩「绝对非破坏」:配合任何选项都不会停机(含 -f),可当参数解析探针使用(4.4 节)。老教程中「-w 用于构造 wtmp 记录」的说法在本版本上不成立。
Q5:两次停机落在同一分钟,wtmp 对不上怎么办?
who -b/last -x 的时间戳只有分钟级分辨率,同分钟内的两次停机会出现「boot 时间没变、down 记录时间完全相同」的现象(4.1 节实测)。可靠的区分手段是按时间窗检索 journal 判定行(journalctl --since ... --until ... 配合 grep System Reboot|System Halt|System Power Off),秒级时间戳能精确定位每一次停机的动作类型。
六、参考链接
- halt/reboot/poweroff 共用手册:
man halt(man 8 halt;本实测环境未安装 man 手册页,可在装有 man-db 的系统上查看) - systemctl 手册:
man systemctl(man 1 systemctl) - reboot(2) 系统调用:https://man7.org/linux/man-pages/man2/reboot.2.html
- systemd 官方文档(systemctl / systemd-halt.service / systemd-poweroff.service):https://www.freedesktop.org/wiki/Software/systemd/
- Ubuntu systemd 软件包页(249.11-0ubuntu3.23 源码与变更记录):https://launchpad.net/ubuntu/+source/systemd
- 同族姊妹篇:《shutdown 命令详解与参数实测(Ubuntu 22.04)》《reboot 命令详解与参数实测(Ubuntu 22.04)》《halt 命令详解与参数实测(Ubuntu 22.04)》