桌面条目可停止服务、启动应用程序以及在应用程序关闭时重新启动服务

桌面条目可停止服务、启动应用程序以及在应用程序关闭时重新启动服务

我有一个应用程序(操作系统是 Ubuntu 16.04),它基本上打开相机对视频流执行一些操作。它由 systemd 服务管理:

[Unit]
Description=My Application
After=network.target
StartLimitInterval=0

[Service]
Type=simple
Restart=always
RestartSec=5
User=myuser
WorkingDirectory=/opt/foo/
ExecStart=/opt/foo/myapplication

[Install]
WantedBy=multi-user.target

然后我有一个桌面条目,可以停止服务并使用参数重新运行我的应用程序:

[Desktop Entry]
Name=Myapp
Type=Application
Exec=/opt/foo/launcher.sh
Terminal=true
Path=/opt/foo/
Categories=None;

这是我的启动器:

#!/bin/bash
service myservice stop
/opt/foo/myapplication --debug

这是有效的,无论如何,当我关闭桌面条目启动的应用程序时,我找不到重新启动服务的方法。我尝试在启动器末尾添加服务重新启动,但它不起作用,因为当我关闭运行应用程序的终端时,我认为的所有内容都会被终止。我该怎么做?

答案1

您可以编写一个单元文件,例如/etc/systemd/system/myprocess.service

[Unit]
Description=My Process

[Service]
ExecStart=/bin/myprocess
Restart=always

[Install]
WantedBy=multi-user.target

然后在桌面入口创建一个启动器来做

systemctl start myprocess.service

但请记住不要在启动时启用该服务,以便您可以从可执行条目手动启动它。
编辑:
如果您还需要在调试模式下运行,则需要使用该--debug参数创建另一个服务单元。您可以创建另一个桌面条目来指向看起来像的脚本(只是代表性的想法)

systemctl stop myprocess.service // to stop previous service
systemctl start processwithdebug.servce // to debug

答案2

你可以让 systemd 为你用第二个单元 B 做一些工作,方法是说它Conflicts用第一个单元 A;那么当你启动B时,它就会停止A。遗憾的是,当B停止时,A默认不会重新启动,但你可以添加一行OnFailure;如果 B 失败退出,A 将启动。为了确保 B 正常退出时失败,您可以使用ExecStop将返回代码设置为非零。

A、服务:

[Service]
Type=simple
ExecStart=/opt/foo/myapplication

B、服务:

[Unit]
Conflicts=A.service
OnFailure=A.service
[Service]
Type=simple
ExecStart=/opt/foo/myapplication --debug
ExecStop=/usr/bin/false

答案3

您可以使用锁定文件来确保应用程序只有一个实例运行。不要systemctl stop myservice在启动器中运行systemctl restart myservice,并在需要重新启动应用程序的 5 秒内,在获取锁定文件后启动调试版本:

systemctl restart myservice
flock /opt/foo/mylock /opt/foo/myapplication --debug

并更改单元文件以使用相同的锁:

ExecStart=/usr/bin/flock /opt/foo/mylock /opt/foo/myapplication

它将在 5 秒后重新启动,然后等待获取锁,并在运行应用程序时保持它。锁定文件可以位于任何地方。您实际上可以用作/opt/foo/myapplication锁定文件,但如果您重新编译它或其他内容,当它发生更改时您将失去锁定。

相关内容