如何在不使用物理开关/插座的情况下立即(1 到 5 秒)关闭计算机?

如何在不使用物理开关/插座的情况下立即(1 到 5 秒)关闭计算机?

是否有任何命令/程序可以让我立即关闭我的系统(1 到 5 秒)?

更新(2015年):感谢那些建议关闭电源插座的人。:D

更新(2016年):@technophile 建议我应该在问题中添加一些信息来描述问题的性质 - 主要是我试图解决哪种情况。这是几年前提出这个问题的场景。

我们正在构建一个系统,部署在公共场所(如机场、酒店等)。人们可以使用该系统上网、查看电子邮件,甚至使用信用卡进行预订等。构建的系统确保第二个用户无法获得该系统前一个用户的信息(电子邮件、信用卡),即使以某种方式安装了键盘记录器之类的软件。系统如何确保这一点?嗯,详细信息不能共享,因为这不是公开信息。但我们开发了一种方法,让系统的新用户始终拥有全新的操作系统(就像是新安装的一样)。唯一的问题是,我们必须在第一个用户离开机器后立即关闭机器并重新启动它。

我希望关机能够立即完成( - 这就是问题所在)并且下次启动也能够非常快,为此我研究并尝试了大量的 Linux 发行版,从 Damn Small Linux 到 Slackware 到 Debian 等等,但那是另一个故事。

答案1

sudo shutdown -h now

答案2

您可以以 root 身份或以对该文件具有写权限的任何用户身份将“o”写入 /proc/sysrq-trigger,从而立即关闭机器而无需同步磁盘。

作为 shell 脚本它看起来像这样

#!/bin/sh
echo o >/proc/sysrq-trigger

有一个关于 sysrq 的 sysctl 选项,但该选项仅影响通过键盘触发。

如果你想立即重启而不是关机,你可以发送“b”而不是“o”;但请记住,虽然 sysrq-trigger 是关闭,可能有更快的方法重新开始. 主板固件(BIOS/UEFI)可能需要花费大量时间来重新初始化硬件,因此使用 kexec 来实现重启通常更快,因为硬件仍然保持初始化状态。

如果你使用的是基于 systemd 的系统,并装载了 systemd-boot,则可以运行

systemctl kexec --force

它会在不关闭服务的情况下启动当前内核。它会卸载可写文件系统,但不会对只读文件系统执行任何操作。这可能比使用 sysrq 更快,因为它不涉及 POST 或主板固件中花费的任何其他时间。

如果您使用的是非 systemd 系统,或者使用了 systemd-boot 以外的引导加载程序,则可能需要更直接地使用 kexec。您需要找到所需的 initramfs 和内核映像的路径。它看起来像

kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline
kexec -e

但在您的例子中,您将用这些路径替换所需的 initramfs 和内核路径。这些恰好是 Arch Linux 上的默认路径。

在我的系统上,有 8 个模块 128GiB 内存、16 个内核和 32 个硬件线程、两个 GPU 以及许多需要初始化的板载外围设备。systemctl kexec(不带 --force)所花费的时间还不到使用 sysrq-trigger 重新启动所花费时间的四分之一。

您可能知道,如果您的文件系统挂载为可写,则不建议这样做,即使您认为在挂载时没有向该文件系统写入任何重要内容。即使您不关心该文件系统上数据的完整性,以这种方式关闭或重新启动也会使启动速度变慢。

确保您的持久文件系统均未以可写方式挂载。

答案3

如果没有特殊原因,我不建议你这样做:

kill -SEGV 1   # should generate a core dumps and kernel panic
kill -ABRT 1   # should generate a core dumps and kernel panic
kill -9 1      # On old systems worked nowadays not

这是粗暴的,残酷的,可以考虑 相当于拔掉电源线...

正确的方法shutdown -h nowsudo需要的时候使用。也许
我应该说合法途径;见下文或更好总结


多说几句,又名故事,第一章
始于最初,终于最初。

整个 Linux 依赖于关爱在里面 [1][2]。尽管如此,也有一些忘恩负义,有一段时间上帝啊root 用户可以背叛这份爱,并突然kill以不容置疑的(-9)命令开始。
《礼记》规定了伯爵、公爵和侯爵的使用者在 a 之前调用sudo)。

然后一些巫师制作了一个护身符来保护它(来自《巫师之书man 2 init》)

唯一可以发送给进程 ID 1(即 init 进程)的信号是 init 明确安装了信号处理程序的信号。这样做是为了确保系统不会意外崩溃。

(我们的间谍报告[U1] init 将处理 1 HUP 6 ABRT 11 SEGV 15 TERM 30 PWR 2 INT 10 USR1 14 ALRM 17 CHLD 32)
因此上帝啊root 用户 了解新闻并更改kill -ABRT 1通常kill -SEGV 1会导致内核恐慌和核心转储的命令。

它之所以有效是因为在里面是第一个运行的进程,PID 号为 1 [2b]

这是不安全、不明智的,你会觉得这是不祥之兆和诅咒,但如果你无法切实地动手并拔掉它……

诅咒:它不会在日志中写入,不会终止所有进程并等待它们结束,不会在 HDD 上正确写入更新 inode,也不会卸载文件系统;甚至不介意它会保存图形窗口和 shell 历史记录的选项,以及许多其他超出我们想象的功能...正如我们所说的,这相当于拔掉电源线,或者拔掉笔记本电脑的电池。


正确的方法
“Non nobis, Domine, non nobis, sed nomini tuo da gloriam.”(无我们,主,无我们,不得荣耀),圣殿骑士的座右铭。
合法的(正确)方法是使用shutdown[3]

sudo shutdown -h now

关机安排以安全的方式关闭系统。所有登录用户都会收到系统即将关闭的通知,并且...

-h now他们将没有足够的时间去做那么多事情……


多说几句,又名故事第二章
曾几何时,Unix 人的上空传来了一些逻辑步骤:

一旦系统进程被终止并且文件系统被卸载,系统就会自动停止/关闭或重新启动。这是使用 halt 或 reboot 命令完成的,该命令会同步对磁盘的更改,然后执行实际的停止/关闭或重新启动。[4]

确实,如今我们不再相信三位莫伊莱的存在5]Linux 世界rebootpoweroffhalt[6]: 这现代科学ls -l $(which poweroff halt reboot)之一,为这个黑暗时代带来了新的曙光,并向我们揭示了只存在一个真正的命令,可以解析所有选项,man reboot以便我们最终可以自由地要求采取与他们的命令名称相矛盾的行动!(halt -preboot -p,...... )poweroffshutdown -rreboot

现在一切似乎都明朗了,谣言声称[7]地狱systemd 工具集 [8]一场革命发生了,让整个上层世界. 感谢向后兼容垫片我们根本没有注意到重启、关机、停止[6]甚至 telinit [9]并关闭[3]都已经绑定到新国王 systemctl [10] . 请聆听JdeBP The Bard原声讲述整个故事[9]因为我已经没有呼吸了。

如果你是 Ubuntu 的追随者,你可能仍然会注意到这些说法[11]


中土世界halt -f,,,inittelinitsystemctl
寻找解决方案的速度比正确的解决方案更快,但同样明智。

systemctl --force --force poweroff  # the most close to kill -9 1 
systemctl --force poweroff          # rough but still safe
sudo halt -f                                       # rough
sudo telinit 0        # or 6                       # safe
kill -SIGINT 1        # cause reboot   as the reboot command
kill -SIGRTMIN+4 1    # cause shutdown as the halt command

无论您是否处于 systemd 之下,您都应该能够在不调用所有正确的关机程序的情况下停止计算机(并且速度更快):

  1. halt -f指定选项-f(请注意,您需要-f避免关机过程)使用上述命令,使用sudo poweroff -f或甚至使用sudo reboot -f -h。实际上,我们可以从man reboot(和等效命令)中了解到需要指定选项-f以避免调用关机:

当调用- 力量或者在运行级别 0 或 6 中,此工具会自行调用 reboot(2) 系统调用(传递 REBOOTCOMMAND 参数),并且直接重启系统

否则,这将调用shutdown(8)工具使用适当的参数,而无需传递 REBOOTCOMMAND 参数。

-f,--force
不会调用关机(8),而是执行名称所期望的实际操作

  1. 此外,您还可以使用telinit [2b](或init直接)

     sudo telinit 0    # or 6
    

告诉 init 改变运行级别...但是如果是这样为什么不直接杀死它?

  1. 在 systemd 下,您可以使用 unwise double 选项--force --force

     systemctl --force --force poweroff  
    

阅读 systemctl 手册[10]

-f, --force
与 enable 一起使用时,覆盖任何现有的冲突符号链接。
halt,,poweroffreboot或 kexec,执行所选操作而不关闭所有单元。但是,所有进程将被强制终止,所有文件系统都将被卸载或以只读方式重新挂载。因此,这是一个激进但相对安全的选项,用于请求立即重启。如果对这些操作指定两次 --force,它们将立即执行,而不会终止任何进程或卸载任何文件系统。警告:在任何这些操作中指定两次 --force可能会导致数据丢失。

Ps> 从尾巴中获取关于变体的灵感 JdeBP The Bard [7]

答案4

poweroff

这应该适用于大多数常见发行版。与 不同shutdown,在许多系统上,您可以以普通用户身份执行此操作(无需 sudo)。

编辑:进一步阅读:

相关内容