systemd 忽略单元文件中的 ExecStop,将其作为 ExecStart 的一部分运行

Jay*_*ald 4 virtualbox systemd 16.04

我试图让几个 VirtualBox 映像在启动时自动启动,并在主机关闭前正确关闭。我有一个 bash 脚本,/usr/local/bin/vmctl.sh它使用对 VBoxManage 的调用来处理启动和停止来宾图像。start 调用非常简单 - 它只是遍历图像列表并调用VBoxManage startvm --type headless "<imgname>"然后退出 0。stop 调用循环遍历列表并调用VBoxManage controlvm "<imgname>" acpipowerbutton然后循环直到VBoxManage list runningvms返回一个空列表或在退出 0 之前经过 60 秒。运行脚本命令行完美运行。

我在以下位置设置了一个单元文件/lib/systemd/system/vmctl.service

[Unit]
Description=VirtualBox Control
After=virtualbox.service

[Service]
ExecStart=/usr/local/bin/vmctl.sh start
ExecStop=/usr/local/bin/vmctl.sh stop

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

当我运行时systemctl start vmctl.service,它会同时调用开始和停止线。当我打电话时systemctl stop vmctl.service,系统日志中有一个条目指出Stopped VirtualBox Control但它没有做任何事情。

我是 systemd 的新手。我最近将这个 Ubuntu 盒子升级到 16.04。我很确定对于我没有看到的这种行为有一个简单的解释。

谢谢!


根据马克的建议更新:

我使用systemd-analyze verify /etc/systemd/system/vmctl.service(将文件移到那里后 - 感谢提示)确认了语法。然后我按照您的建议更改了 ExecStart 和 ExecStop ,运行systemctl daemon-reload并仍然看到相同的行为。日志显示在调用时都在执行systemctl start vmctl,但在运行时都不显示systemctl stop vmctl

# journalctl -u vmctl | tail
.
.
.
Apr 06 19:28:18 macmi10-builder systemd[1]: Started VirtualBox Control.
Apr 06 19:28:18 macmi10-builder echo[13901]: I started
Apr 06 19:28:18 macmi10-builder echo[13904]: I stopped
Apr 06 19:28:33 macmi10-builder systemd[1]: Stopped VirtualBox Control.
Run Code Online (Sandbox Code Playgroud)

Des*_*son 6

正如其他人所提到的,问题是vmctl.sh立即退出。与@Christophe 的回答相反,分叉很vmctl.sh可能不起作用,因为很可能不会分叉。您需要的是一种oneshot服务,具有RemainAfterExit=true. 如果您只是将其更改为oneshot,您将获得完全相同的行为。该RemainAfterExit部分告诉它即使在ExecStart退出之后,该服务仍应被视为正在运行,因此不应运行ExecStop(s)。