如何在关机过程*开始*时运行脚本?

如何在关机过程*开始*时运行脚本?

在 Ubuntu 19.10 中,我尝试创建一个脚本,以便在系统关闭时正常关闭用户的虚拟机,例如以 root 身份运行时

runuser -l jamie -c "vboxmanage controlvm \"Windows 10" suspend"

我根据我能找到的每个示例尝试了多种技术systemctl,但都不起作用:在我的脚本运行之前总会有一些东西杀死虚拟机,并且它在日志中显示:

runuser[11997]: pam_unix(runuser-l:session): session opened for user jamie by (uid=0)
Nov 12 23:51:48 media2 shutdown[11979]: VBoxManage: error: Machine 'Windows 10' is not currently running

至少我有理由相信这就是我收到此消息的原因——如果我不在正确的用户上下文中,它会说机器不存在。

有许多类似的问题,但这些问题对我都没有用,我几乎尝试了所有我能从类似问题中找到的变体这里这里这里这里, 和这里, 例如:

[Unit]
Description=Run Scripts at Start and Stop

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/home/jamie/.scripts/shutdown

[Install]
WantedBy=multi-user.target

(以及涉及其他目标、选项等的许多其他变体)。这些在末尾运行脚本,multi-user.target这似乎太晚了。使用reboot.targetetc 的结果相同 - 脚本显然运行得太晚了。

我尝试使用这种技术-- 创建在多用户目标之后运行的新自定义目标 -- 但我无法注册自定义目标;它只是让 gnome 崩溃了。我在其他地方找不到有关此方法的进一步讨论。

有什么想法我可以如何在正在运行的进程终止之前成功拦截重启/关机事件?

答案1

此解决方案分为两部分。第一部分是创建脚本,第二部分是创建 systemd 服务文件来运行该脚本。

第 1 部分:创建脚本:autovm.sh

注意:您可以通过以下方式找到虚拟机的 UUID:VBoxManage list vms

sudo nano /bin/autovm.sh

#!/bin/bash

VMUSER="username"
VMNAME="21b3afd8-8f71-4c31-9853-ce9aa2eb58fb"

case "$1" in
    start)
    echo "===Starting VirtualBox VM==="
    sudo -H -u $VMUSER VBoxManage startvm "$VMNAME" --type headless
    ;;
    stop)
    echo "===Shutting down Virtualbox VM==="
    sudo -H -u $VMUSER VBoxManage controlvm "$VMNAME" acpipowerbutton
    sleep 20
    ;;
    *)
    echo "Usage: /bin/autovm.sh {start|stop}"
    exit 1
    ;;
esac

exit 0

现在使autovm.sh脚本可执行并将其放置到:/bin/

第 2 部分:创建autovm.service文件/etc/systemd/system/(不要使此文件可执行)

sudo nano /etc/systemd/system/autovm.service

[Unit]
Description=Autostart VM

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 20
ExecStart=/bin/autovm.sh start
ExecStop=/bin/autovm.sh stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

现在通过以下方式启用该服务:

sudo systemctl enable autovm.service

相关内容