我在这里做错事了。我希望 SystemD 运行 bash 脚本。 bash 脚本检查 GUI 应用程序是否正在运行,如果没有运行,则 bash 脚本启动 GUI 应用程序;如果 GUI 应用程序正在运行,则 bash 脚本退出。
我可以手动运行 bash 脚本,但它不能与systemctl --user start make-run.sh
.就本问题而言,GUI 应用程序是xterm
.但实际上,目标 GUI 应用程序是查泰里诺。我将其更改为xterm
,因为我假设大多数人不使用 Chatterino。 Bash 脚本是可执行的。我的单元文件位于~/.config/systemd/user/
.我也在Type=oneshot
单位文件中尝试过,但没有成功。
bash脚本
#!/bin/bash
# ensure a process is always running
export DISPLAY=:0 # needed if running a gui app
process=xterm
makerun="/usr/bin/xterm"
if ps ax | grep -v grep | grep $process > /dev/null
then
exit
else
$makerun &
fi
exit
单位档案
[Unit]
Description=Make run
[Service]
Environment="DISPLAY=:0"
ExecStart=/usr/bin/bash /home/ladlelord/bin/make-run.sh
[Install]
WantedBy=graphical.target
答案1
GAD3R 很接近,但我建议:
DISPLAY
根本不要设置。总线--user
隐式地设置了这一点。通过根本不设置它,即使您更改了显示设置并最终登录到不同的显示器,您也可以使其正常工作。这意味着:DISPLAY
从服务和脚本中删除这些行。- 在本
[Install]
节中,使用graphical-session.target
.在为该用户准备好图形环境后,将提高该目标。常见的不当错误有:graphical.target
仅在系统总线上,并在出现登录屏幕(即 GDM 或 lightdm)时引发。对于 GUI 用户应用程序来说,现在启动还为时过早。multi-user.target
也在系统总线上,并且在任何人都可以登录(包括通过 ssh 或 TTY)时立即引发。这当然是不合适的,因为无法保证用户已登录或图形环境可用。default.target
位于用户总线上,但如果您通过 ssh 登录(没有图形会话),则可以引发该错误。在某些情况下,您的服务会失败。
xterm
如果没有实例(无论用户是谁)正在运行,您的脚本就会运行。这使得它有点不必要,并且实际上使服务可以立即退出而不执行任何操作(这可能不是您启动该服务时想要的)。您可以通过删除脚本并使用来简化此操作ExecStart=/usr/bin/xterm
。- 如果您确实想保留脚本,请考虑使用
Type=forking
而不是隐式Type=simple
.您运行bash
,它启动xterm
,然后退出。因为Type=simple
,bash
是主要过程。当bash
结束时,systemd
看到主进程退出并且应该认为服务已完成(非活动-死亡)。然后它将继续清理(杀死)任何孤立的进程,包括xterm
.当您使用 时Type=forking
,您会告诉systemd
您监视生成的进程并让它们成为主进程。PIDFile=
可用于显式定义哪个派生进程成为主要进程。但如果你只是这么做的话,所有这些都是不必要的ExecStart=/usr/bin/xterm
。
这是我的完整建议(假设您删除脚本):
[Unit]
Description=Make run
[Service]
ExecStart=/usr/bin/xterm
Restart=on-failure
[Install]
WantedBy=graphical-session.target
或者这个(使用脚本):
[Unit]
Description=Make run
[Service]
ExecStart=/usr/bin/bash /home/ladlelord/bin/make-run.sh
Restart=on-failure
Type=forking
[Install]
WantedBy=graphical-session.target
答案2
在您的 bash 脚本中,替换export DISPLAY=:0
为:
export DISPLAY=:0.0
编辑make-run.sh.service
如下:
[Unit]
Description=Make run
[Service]
Environment="DISPLAY=:0"
ExecStart=/usr/bin/bash /home/ladlelord/bin/make-run.sh
Restart=on-failure
Type=forking
[Install]
WantedBy=graphical.target
然后:
systemctl --user daemon-reload
systemctl --user restart make-run.sh.service
编辑