由 SystemD 调用的 Bash 脚本启动 GUI 应用程序

由 SystemD 调用的 Bash 脚本启动 GUI 应用程序

我在这里做错事了。我希望 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 很接近,但我建议:

  1. DISPLAY根本不要设置。总线--user隐式地设置了这一点。通过根本不设置它,即使您更改了显示设置并最终登录到不同的显示器,您也可以使其正常工作。这意味着:DISPLAY从服务和脚本中删除这些行。
  2. 在本[Install]节中,使用graphical-session.target.在为该用户准备好图形环境后,将提高该目标。常见的不当错误有:
    • graphical.target仅在系统总线上,并在出现登录屏幕(即 GDM 或 lightdm)时引发。对于 GUI 用户应用程序来说,现在启动还为时过早。
    • multi-user.target也在系统总线上,并且在任何人都可以登录(包括通过 ssh 或 TTY)时立即引发。这当然是不合适的,因为无法保证用户已登录或图形环境可用。
    • default.target位于用户总线上,但如果您通过 ssh 登录(没有图形会话),则可以引发该错误。在某些情况下,您的服务会失败。
  3. xterm如果没有实例(无论用户是谁)正在运行,您的脚本就会运行。这使得它有点不必要,并且实际上使服务可以立即退出而不执行任何操作(这可能不是您启动该服务时想要的)。您可以通过删除脚本并使用来简化此操作ExecStart=/usr/bin/xterm
  4. 如果您确实想保留脚本,请考虑使用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

编辑

graphical.target 根据以下情况比较适合@斯图尔特 建议

相关内容