如何在Linux上检测挂起的系统关闭?

341*_*008 20 c linux system-shutdown sigterm

我正在开发一个需要检测系统关闭的应用程序.但是,我没有找到任何可靠的方式来获取此事件的通知.

我知道在关机时,我的应用程序会收到一个SIGTERM信号后跟一个SIGKILL.我想知道是否有任何方法可以查询a SIGTERM是否是关闭序列的一部分

有没有人知道是否有办法以编程方式查询(C API)?

据我所知,系统没有提供任何其他方法来查询即将发生的关机.如果是这样,那也可以解决我的问题.我也一直在尝试runlevels,但改变runlevels似乎是即时的,没有任何预先警告.

use*_*937 11

也许有点晚了.是的,您可以通过调用runlevel命令来确定SIGTERM是否处于关闭过程中.例:

#!/bin/bash
trap "runlevel >$HOME/run-level; exit 1" term
read line
echo "Input: $line"
Run Code Online (Sandbox Code Playgroud)

保存它,比方说,term.sh然后运行它.通过执行killall term.sh,您应该能够查看和调查run-level主目录中的文件.通过执行以下任何一项:

sudo reboot
sudo halt -p
sudo shutdown -P
Run Code Online (Sandbox Code Playgroud)

并比较文件中的差异.然后你应该知道如何做到这一点.


341*_*008 6

无法确定a SIGTERM是否是关闭序列的一部分.要检测关闭序列,您可以使用rc.dereOn和Eric Sepanson建议的使用脚本,也可以使用DBus等机制.

但是,从设计的角度来看,SIGTERM即使它不是关闭的一部分也没有意义.SIGTERM主要目的是礼貌地要求应用程序干净地退出,并且SIGTERM如果他/她不希望应用程序退出,则具有足够权限的人不太可能发出.


小智 5

从男人关机:

如果使用time参数,则在系统关闭前5分钟/etc/nologin创建文件以确保不允许进一步登录.

所以你可以测试存在/etc/nologin.它不是最佳的,但可能是最好的.


Vag*_*err 5

它有点黑客但如果服务器正在运行 systemd 如果你可以运行

/bin/systemctl list-jobs shutdown.target

......它会报告......

JOB UNIT            TYPE  STATE
755 shutdown.target start waiting     <---- existence means shutting down

1 jobs listed.
Run Code Online (Sandbox Code Playgroud)

...如果服务器正在关闭或重新启动(提示:如果您想专门查找,则有一个 reboot.target )

No jobs running.如果它没有被关闭,你会得到。

您必须解析有点混乱的输出,因为 systemctl 不会为两个结果返回不同的退出代码。但它看起来确实相当可靠。但是,如果您更新系统,则需要注意消息中的格式更改。