为什么`at`不执行GUI应用程序?

为什么`at`不执行GUI应用程序?

在我的 Ubuntu 20 桌面上,我计划gedit从现在开始运行,但没有任何反应。这是为什么?

$ echo "echo foo > at.sux" | at now + 1
warning: commands will be executed using /bin/sh
job 8 at Tue Jun  2 21:47:00 2020

$ echo `which gedit` | at now + 1
warning: commands will be executed using /bin/sh
job 9 at Tue Jun  2 21:47:00 2020

$ atq
9   Tue Jun  2 21:47:00 2020 a dandv
8   Tue Jun  2 21:47:00 2020 a dandv

# A minute later

$ cat at.sux
foo

$ ps auxf | grep gedit  # nothing but grep

$ `which gedit`  # launches gedit

echo "gedit &" | at now + 1按照评论中的建议进行了尝试,但gedit一分钟后仍然没有运行。

答案1

GUI 应用程序通过服务器访问屏幕。当您从命令行或菜单运行它们时,环境会告诉应用程序如何连接到服务器。

但是,当您运行at命令时,环境不包含该信息(您可以at -c JOBNUMBER查看应用程序继承的环境),这就是应用程序将启动但无法运行的原因。

要运行 GUI 应用程序,您可以指定服务器,或者使用以下内容调用应用程序(您的显示可能有所不同):

DISPLAY=:0 application

或者,根据应用:

application --display :0

您可能需要更改服务器权限,并且可能需要其他服务,但无法从会话外部访问(例如 dbus)。

答案2

GUI 应用程序(例如)gedit可能与该命令一起工作,也可能不与该命令一起工作at。这取决于您是否使用基于 X11 的显示服务器(例如 )Xorg或基于协议Wayland(例如Weston.

使用哪个显示服务器取决于您的发行版、发行版的版本和用户配置。例如,默认情况下,Ubuntu 20 使用基于 X11 的显示服务器,而 Fedora 32 使用 Wayland。

at命令将当前环境的大部分内容存储at/var/spool/at.有一些例外,包括 DISPLAY、TERM、SHELLOPTS、EUID、GROUPS、PPID、UID 等。这些具体不存储在at作业文件中。

因此,如果您创建一个at作业来在基于 X11 的服务器环境中启动 GUI 应用程序,它将失败,因为没有DISPLAY可用的变量。

解决方法很简单(假设您的屏幕是:0):

$ echo 'DISPLAY=:0 gedit' | at now + 1 min

或者更一般地说:

$ echo 'DISPLAY="$DISPLAY" gedit' | at now + 1 min

Wayland 使用不同的环境变量,即WAYLAND_DISPLAY,通常设置为wayland-0。该命令保留此变量,因此,当作业运行at时会启动 GUI 应用程序。at

相关内容