我开始怀疑 Ubuntu 并没有告诉正在运行的应用程序它正在关闭以让它们正确退出,而是强制它们退出。
如果我在关机时让 chrome 保持打开状态,当我在启动后再次打开它时,它会说上次没有正确关闭,LibreOffice 不会询问我是否要保存我的文档,并且我正在制作一个需要在退出时运行一些代码的应用程序,但在计算机关闭时不允许这样做。
据我了解,SIGTERM 会首先发送给所有进程,让它们干净地退出,如果它们不退出,则会发送 SIGKILL 以强制它们退出。Ubuntu 似乎根本没有发送 SIGTERM,或者在发送 SIGKILL 之前没有给应用程序足够的时间。
有什么方法可以修复这个问题吗?
我正在运行 Ubuntu 16.04,但这个问题在 15.10 中也存在。我不知道以前是否也存在这个问题,因为我开始使用 Ubuntu 时 15.10 是最新版本。
编辑:我使用 Unity,通过按下右上角的齿轮并选择关机来关闭我的电脑,但如果sudo halt
在终端中运行,问题是一样的。
编辑:我观察到仅在注销时出现相同的行为。我猜想信号应该在注销时发送,因此问题出现在关机和注销时。
答案1
不幸的是,它并不是这样工作的。许多确实有信号处理程序的程序不会阻止信号显示确认对话框。信号处理通常很少或缺失。
您无需关机即可轻松尝试。只需向正在运行的 Firefox 或 LibreOffice 进程发送 SIGTERM 即可:
$ pkill firefox
通常,Firefox 可能会询问您是否确实要关闭它。此外,它通常需要一段时间才能关闭,特别是当它运行了很长时间并且使用了超过 1 GB 的 RAM 时 - 在关闭最后一个窗口后,进程通常需要一分钟才能终止。当您发送 SIGTERM 时,这些都不会发生,进程会立即终止。
但是,某些桌面环境在关闭之前会关闭所有打开的窗口。与 SIGTERM 不同,以编程方式关闭窗口就像单击该窗口的 X 按钮或Alt+ F4。这也是另一个答案中的脚本所做的 - 它使用 wmctrl 优雅地关闭所有打开的窗口。
关闭窗口时,程序不会着急,它会关闭该窗口内的所有内容,例如打开的选项卡,如果有未保存的工作,它还可以显示一个对话框窗口。一旦应用程序的所有打开的窗口都关闭,进程通常会在之后不久终止。
因此,这取决于您的桌面环境(假设您使用桌面环境来关机而不是sudo poweroff
)。例如,KDE 应该等待打开的窗口关闭后再关机,而 MATE 则不会。
底线:关机前手动关闭所有打开的窗口。或者使用等待所有窗口关闭的桌面环境。
答案2
值得一提的是,前段时间我在 Manjaro 论坛上发现了这个过程:
close_apps () {
WIN_IDs=$(wmctrl -l | grep -vwE "Desktop$|xfce4-panel$" | cut -f1 -d' ')
for i in $WIN_IDs; do wmctrl -ic "$i"; done
# Keep checking and waiting until all windows are closed
while [ "$WIN_IDs" != "" ]; do
sleep 0.1;
WIN_IDs=$(wmctrl -l | grep -vwE "Desktop$|xfce4-panel$" | cut -f1 -d' ')
done
}
您可以在自己的脚本中调用它来在关机(或重启)之前关闭所有打开的应用程序。
唯一的问题是,它是为 Xfce 创建的,因此需要 Unity DE 强加的更改。如果能得到更有知识的人的一点帮助,就能很好地解决 OP 的问题。
答案3
实际上,Ask 上有一部分脚本可以关闭所有窗口,并且不依赖于任何特定的 DE。第二和第三个答案特别有用。只需再写几行,并在面板或桌面上创建一个启动器,您就可以实现在您使用的 DE 中工作的正常关机。