我在这里做错了什么。我希望 SystemD 运行一个 bash 脚本。bash 脚本检查 GUI 应用程序是否正在运行,如果没有运行,则 bash 脚本启动 GUI 应用程序;如果 GUI 应用程序正在运行,则 bash 脚本退出。
我可以手动运行 bash 脚本,但不能使用systemctl --user start make-run.sh
. 对于这个问题,GUI 应用程序是xterm
. 但实际上,目标 GUI 应用程序是Chatterino。我将其更改为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
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
看到主进程退出并且应该认为服务已完成(inactive-dead)。然后它将继续清理(杀死)任何孤立的进程,包括xterm
. 当你使用 时Type=forking
,你告诉systemd
观察衍生的进程并让它们成为主进程。PIDFile=
可用于明确定义哪个衍生进程成为主要进程。但是,如果您只是ExecStart=/usr/bin/xterm
.这将是我的全部建议(假设您删除了脚本):
或者这个(使用脚本):
在您的 bash 脚本中,替换
export DISPLAY=:0
为:编辑
make-run.sh.service
如下:然后:
编辑
根据@Stewart 的建议
graphical.target
, 它更合适。