我想在每次启动系统时以 root 身份执行脚本。我写了一个shell脚本:
# cat /home/root/demo_wrap.sh
#!/bin/bash
`/home/root/demo_start.sh` > /dev/null &
当我从 shell 调用它时效果很好。我编写了以下服务文件:(根据埃德加·马加隆的评论进行更新):
# cat /etc/systemd/system/demo_start.service
[Unit]
Description=starts the MH11 demo on EVK
[Service]
Environment="DISPLAY=:0"
Type=forking
XAUTHORITY=/home/root/.Xauthority
ExecStart=/home/root/demo_wrap.sh
[Install]
WantedBy=graphical.target
(我也尝试过DISPLAY:1
s ,但XAUTHORITY=/run/user/0
没有成功)
但由于某种原因,# systemctl start demo_start
不会调用应用程序但报告:
[[0;1;31m*[[0m demo_start.service - starts the MH11 demo on EVK
Loaded: loaded (/etc/systemd/system/demo_start.service; enabled; vendor preset: disabled)
Active: [[0;1;31mfailed[[0m (Result: exit-code) since Wed 2022-05-11 18:58:25 UTC; 1min 11s ago
Process: 251 ExecStart=/home/root/demo_wrap.sh (code=exited, status=0/SUCCESS)
Main PID: 252 (code=exited, status=127)
May 11 18:58:18 smarc-rzv2l systemd[1]: Starting starts the MH11 demo on EVK...
May 11 18:58:18 smarc-rzv2l systemd[1]: Started starts the MH11 demo on EVK.
May 11 18:58:25 smarc-rzv2l demo_wrap.sh[254]: error: XDG_RUNTIME_DIR not set in the environment.
May 11 18:58:25 smarc-rzv2l demo_wrap.sh[254]: Connecting to display server failed!: No such file or directory
May 11 18:58:25 smarc-rzv2l demo_wrap.sh[254]: [ERROR] Wayland::init failed
May 11 18:58:25 smarc-rzv2l demo_wrap.sh[252]: /home/root/demo_wrap.sh: line 2: RZ/V2L: No such file or directory
May 11 18:58:25 smarc-rzv2l systemd[1]: [[0;1;39m[[0;1;31m[[0;1;39mdemo_start.service: Main process exited, code=exited, status=127/n/a[[0m
May 11 18:58:25 smarc-rzv2l systemd[1]: [[0;1;38;5;185m[[0;1;39m[[0;1;38;5;185mdemo_start.service: Failed with result 'exit-code'.[[0m
而export XDG_RUNTIME_DIR="/run/user/0"
设置为/etc/profile
:
export XDG_RUNTIME_DIR=/run/user/$UID
weston 显示管理器启动并在 HDMI 屏幕上正确显示。
环境:
这是在一个嵌入式平台上,带有 Yocto 构建的发行版,运行 Weston 合成器。当我在 Weston 中启动 shell 窗口并输入 时echo $DISPLAY
,它不会打印任何我期望的:0
或:1
(根据埃德加·马加隆,如下)。当终端窗口正确显示在 Weston 桌面上时。这是一个嵌入式参考平台,只有一个用户root
。它没有连接到网络,任何人都无法通过将任何其他硬件方式连接到它来访问它。安全不是问题!
我在系统上发现了以下内容:
# cat /lib/systemd/system/weston\@.service
[Unit]
Description=Weston Wayland Compositor
RequiresMountsFor=/run
Conflicts=plymouth-quit.service
After=systemd-user-sessions.service plymouth-quit-wait.service
[Service]
User=%i
PAMName=login
EnvironmentFile=-/etc/default/weston
StandardError=journal
PermissionsStartOnly=true
IgnoreSIGPIPE=no
ExecStart=/usr/bin/weston-start -v -e -- $OPTARGS
我的演示应该在此之后开始,但这有点奇怪:
# systemctl status weston.service
向我展示:
[[0;1;32m*[[0m weston.service
Loaded: loaded (/etc/init.d/weston; generated)
Active: [[0;1;32mactive (exited)[[0m since Wed 2022-05-11 18:57:23 UTC; 33min ago
Docs: man:systemd-sysv-generator(8)
Process: 189 ExecStart=/etc/init.d/weston start (code=exited, status=0/SUCCESS)
May 11 18:57:22 smarc-rzv2l systemd[1]: Starting weston.service...
May 11 18:57:23 smarc-rzv2l systemd[1]: Started weston.service.
May 11 18:57:34 smarc-rzv2l weston[196]: Connecting to display server failed!: No such file or directory
May 11 18:57:34 smarc-rzv2l weston[196]: [ERROR] Wayland::init failed
May 11 18:57:35 smarc-rzv2l weston[190]: /etc/profile.d/zz1-demo_wrap.sh: line 2: RZ/V2L: No such file or directory
而韦斯顿已启动并运行良好。
答案1
发生的情况是您的服务文件尝试在其他服务启动之前执行您的应用程序。您需要添加demo_start.service
指令After
,告诉该服务仅在其他服务已经运行时才运行。鉴于您需要 Weston 合成器,您必须将 添加weston.service
到指令中。
此外,对于XDG_RUNTIME_DIR
错误,同样的逻辑也适用。对于这种情况,您需要添加 systemd-user-sessions.service,以便/run/user/0
在尝试执行应用程序之前创建目录。除此之外,您还需要将指令设置Environment
为目录路径XDG_RUNTIME_DIR
。
您的demo_start.service
文件应包含以下指令:
[Unit]
Description = starts the MH11 demo on EVK
After = weston.service systemd-user-sessions.service
[Service]
User = root
Environment = "XDG_RUNTIME_DIR=/run/user/0"
ExecStart = /home/root/demo_wrap.sh
[Install]
WantedBy = multi-user.target