启动时无法运行无限运行的命令

启动时无法运行无限运行的命令

我想使用 gpu-screen-recorder 来录制重播。我使用 flatpak 安装了它,并使用以下命令启动重播模式:

flatpak run --command=gpu-screen-recorder com.dec05eba.gpu_screen_recorder -w DP-1 -f 60 -o ~/Videos/Captures -c mp4 -r 150 -a alsa_output.usb-BEHRINGER_UMC202HD_192k-00.HiFi__hw_U192k__sink.monitor

该过程占用了当前终端。

由于我不想让被阻塞的终端窗口持续运行,而只想让它在启动时启动,所以我创建了一个~/scripts/startup/gpu-recorder-flatpak-command.sh要在启动时运行的脚本。该脚本是可执行的,并且有一个 shebang。如果我只是在终端中输入文件名,它就会按预期工作。这意味着,我可以在另一个终端中发送命令 ( killall -SIGUSR1 gpu-screen-recorder),并将过去 2.5 分钟的视频保存到指定位置。

现在,为了让它在启动时启动,我尝试使用 cron 并尝试创建自己的 systemd 服务。

为了使用 cron,我尝试使用crontab -e放入@reboot ~/scripts/startup/gpu-recorder-flatpak-command.sh cronjob 文件中。我也尝试放入@reboot sleep 10; ~/scripts/startup/gpu-recorder-flatpak-command.sh,但似乎没有任何改变。

当 cron 不起作用时,我并没有真正检查原因,我只是转到 systemd 路由。我的服务文件位于/etc/systemd/system/gpu-screen-replay.service,其中包含以下内容:

[Unit]
Description=GPU screen record replay service
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=1
User=lenny
ExecStart=/home/meekah/scripts/startup/gpu-recorder-flatpak-command.sh

[Install]
WantedBy=multi-user.target

我确实执行了systemctl enable gpu-screen-replay.service,并且在运行时systemctl我的服务被列为loaded active running

您有什么建议我可以尝试或检查错误消息吗?我尝试检查,journalctl但似乎只是启动了服务而没有错误。

答案1

这看起来像是您应该作为 GUI 会话的一部分启动的东西,而不是作为系统服务。

创建*.desktop文件~/.config/autostart/是当今大多数图形环境支持的传统方法。最基本的此类文件如下所示:

[桌面条目]
类型=应用程序
名称=某些应用程序
执行=〜/whatever.sh

更一般的答案

您需要运行该程序

  1. (或之后)正确的阶段初创– “启动”是一个过程,而不是一个瞬间,并且并非所有系统组件都在同一时刻可用;一些设施可用较早,其他设施可用较晚。

    没有列出任何依赖项的 systemd .service 将被分组到“basic.target 之后但尽可能早”,这很可能为时过早。

    如果您的程序通过 X11 显示 GUI 窗口 - 即使它不使用 X11 进行实际录制 - 这仍然意味着它依赖于 X11 的启动,这是最后发生的事情之一;很多比 cron“@reboot”任务处理得晚。(事实上,X11 在你登录,所以它甚至不算作一般启动过程的一部分。)

    即使程序不依赖 X11,它也可能希望通过 /dev 访问 GPU,并且很可能在加载 GPU 驱动程序之前运行某些系统服务。(对于 GPU 驱动程序来说,这种情况不太可能发生——如今这些驱动程序都是加载的非常但这仍然是你需要考虑的事情。)

    (而且因为它是一个 Flatpak 应用程序,所以它很可能依赖于只有在您登录时才启动的各种其他用户级服务。)

    因此,每次您需要自动启动某个东西时,您都需要考虑它的依赖项是什么以及如何指定它们(在 systemd 中,有时会使用 来完成[Unit] After=[Unit] Wants=

  2. 在正确的环境– 并非所有进程都在相同环境中运行;这主要指的是“环境变量”,但也指更一般意义上的环境(即各种其他参数)。

    关于环境变量,您的 GUI 会话比服务拥有的要多得多 - 仅设置User=不会自动为您设置它们。具体来说,对于 X11,您需要DISPLAYXAUTHORITY;对于 Wayland,您需要WAYLAND_DISPLAY;对于 PulseAudio(对于-a选项),您需要XDG_RUNTIME_DIR;相当多其他东西依赖于DBUS_SESSION_BUS_ADDRESS。这些是任何 GUI 类的典型“最低限度”。

    还有其他可能构成“环境”的东西,比如用于访问控制的登录会话(即使在您的 UID 下运行的进程属于服务,也可能不会被授予相同的访问权限)。

    因此,对于需要访问任何“用户” GUI 组件的任何东西,最好始终启动程序从内部登录时已设置的 GUI 环境 — 这样它就会继承所有必要的内容,就像您的终端应用程序一样。几乎所有桌面都支持登录时自动启动程序;上述方法~/.config/autostart/是最常见的方法,尽管通常还有其他几种方法。

您有什么建议我可以尝试或检查错误消息吗?我尝试检查 journalctl,但似乎它只是启动了服务而没有错误。

如果 journalctl 没有捕获输出,请尝试查看不带该-u选项的未过滤日志;非常短暂的进程有时可能无法正确标记其相应的单元名称。

检查systemctl restart服务是否正常运行。如果手动重启后服务可以启动,则几乎可以肯定是之前描述的某种“缺少依赖项”问题。

用于systemd-run从终端创建和启动动态服务;这有一个小优势,即您可以使用--pipe甚至--pty直接将服务的输出附加到您的终端(否则常规服务无法做到这一点),同时仍通过 systemd 启动进程。这可能会显示否则不会显示的错误消息。

相关内容