在系统关闭之前使用 systemd 执行脚本?

dai*_*isy 7 shutdown systemd

我写了一个脚本来挂起我所有的 VirtualBox 机器,并在 中放一行/etc/rc.local.shutdown,但它似乎不起作用,

su - XX -c /XX

当我下次启动时,VirtualBox 告诉我机器是 Aborted,所以脚本没有执行。(手动启动该脚本对我有用)

PS我已经启用 shutdown.target

编辑

这个问题似乎更为复杂,比我想象的,我的.bashrc,如果它的运行上tty3,它执行startx,所以当systemd决定关机/重启,它杀死对子级VBoxSVC的过程,而当X会话模具其他的东西。

我还试图破解 的源代码xfsm-shutdown-helper,制作一个systemctl先执行我的脚本的假冒,以上都不起作用。

Mar*_*urg 1

如果我理解正确的话,您希望在 tty3 上的 bash 会话终止之前或 Xserver 终止之前挂起您的 VB 机器。

我相信 systemd 不知道您正在运行的 Xsession,因为您从 .bashrc 启动它,因此很难告诉 systemd 在终止您的 shell 或 Xsession 之前挂起您的 VB。您必须在关闭序列中找到一个“足够早”的位置,这可能很难找到并且在语义上有问题,因为它将“用户内容”与“系统内容”混合在一起

解决方案可能在某种程度上取决于 systemd 终止进程的方式,但以下内容至少应该指出一个好的方向:

在 shell 终止之前

suspendVB() {
        echo "suspending VBs"
        # put real code here
        exit
}

trap suspendVB EXIT
Run Code Online (Sandbox Code Playgroud)

如果您将其作为 bash 的 rc 文件(或将其添加到 .bashrc 中),则其中的代码suspendVB()将在 shell 终止之前执行。您可以通过运行来测试这一点

bash --rcfile xxx
Run Code Online (Sandbox Code Playgroud)

其中文件xxx包含上面的代码。这会在当前 shell 中启动另一个 shell,仅用于测试。当您运行简单的退出时,您将看到:

martin@beaureve:~$ exit
exit
suspending VBs
/home/martin >
Run Code Online (Sandbox Code Playgroud)

然后您就回到了原来的(登录)shell。

您可能需要了解 systemd 实际上如何终止您的登录 shell,并且您可能需要EXIT用其他一些信号进行替换。查找trap命令以了解更多信息。

请注意,当 systemd 使用“-9”(SIGKILL)终止您的进程时,您将无法捕获终止,即您不走运。

在 Xsession 终止之前

或者,您可以在 Xsession 中尝试类似的操作。当 systemd在终止 shell之前终止 Xsession 时,这一点至关重要。您可能想要在 X 启动文件之一(例如 .xinitrc)中插入陷阱 - 查找手册页startxxinit了解更多信息。

如果你的startx文件看起来像我的,那么 xserver 在前台启动,你也可以简单地将挂起命令放在 X 实际启动的行之后(并且根本不使用陷阱):

xinit "$client" $clientargs -- "$server" $display $serverargs
retval=$?
echo " --- suspending VBs ---"
Run Code Online (Sandbox Code Playgroud)

我输入了“挂起 VB”这一行,当我运行时,startx -- vt8我在 vt8 上获得了一个 fullblows (kde) 会话,只有当我注销时,“挂起 VB”这行才会出现在屏幕上。