我正在尝试通过尝试将 xclock 作为服务启动来学习 systemd 服务;服务文件如下
[Unit]
Description=clock
[Service]
Environment=DISPLAY=:0
ExecStart=/usr/bin/xclock
[Install]
WantedBy=graphical.target
有什么想法这里出了什么问题吗?我收到一条错误消息“无法连接到显示器”。
答案1
应用程序需要两件事才能在 X 显示器上打开窗口。它需要知道X显示器的位置;这是由DISPLAY
环境变量传达的。它还需要通过 X 服务器进行身份验证。这是通过 cookie 来传达的,cookie 是 X 服务器启动时生成的秘密值,并存储在只有启动 X 服务器的用户才能访问的文件中。默认的 cookie 文件是~/.Xauthority
.
如果您的 X 服务器使用默认的 cookie 文件位置,则添加Environment=XAUTHORITY=/home/dogs/.Xauthority
将起作用(假设/home/dogs
是在 X 下登录的用户的主目录)。如果您需要查找位置,请参阅我可以以 root 身份在另一个用户的桌面上启动图形程序吗?和在远程 X 显示器上打开窗口(为什么“无法打开显示器”)?
或者,以运行 X 服务器的用户身份运行程序也可以,前提是 cookie 文件位于默认位置(如果不是,您必须找到 cookie 文件,就像在 root 情况下一样)。添加User
指令(例如User=dogs
)。
当然,如果您指定的用户拥有的号码没有 X 显示,则该服务将不会运行。
从 Systemd 启动 GUI 程序是相当奇怪的。它不是为此而设计的。 GUI 程序存在于由用户启动的 X 会话中。 Systemd 用于系统进程。您应该尝试使用守护进程。
答案2
现代方法(2021 年)是不在单元文件中对环境进行硬编码.service
。相反,做这样的事情:
$ cat /etc/X11/xinit/xinitrc.d/50-systemd-user.sh
#!/bin/sh
systemctl --user import-environment DISPLAY XAUTHORITY
if command -v dbus-update-activation-environment >/dev/null 2>&1; then
dbus-update-activation-environment DISPLAY XAUTHORITY
fi
例如,Arch Linux 就是这样做的。
说明:启动X11时,DISPLAY
和XAUTHORITY
环境变量都被继承全部systemd 用户服务单元文件(即由 管理的文件systemd --user
)。
人们可以通过运行来检查这些设置是否正确systemctl --user show-environment
。
通过这样做,您不需要Environment=
在文件中使用指令.service
。
答案3
您可以添加.xinitrc
:
xhost si:localuser:$USER
这个对我有用!