Linux:通过 ssh+screen 启动会话时 wmctrl 无法打开显示

GJ.*_*GJ. 7 linux ssh gdm gnu-screen ubuntu

我在 Ubuntu 机器上使用 wmctrl 从脚本管理窗口,我在 (gnu) 屏幕内运行。

如果我从本地机器启动屏幕会话,wmctrl 工作正常,包括我是否完全关闭终端窗口并在通过 ssh 远程连接到屏幕时发出 wmctrl 命令。相反,如果我使用 ssh 远程连接并启动屏幕,即使我从 Ubuntu 终端本地附加该屏幕会话,wmctrl 也不起作用(返回“无法打开显示”)。

我猜有一些隐藏的屏幕参数没有以允许在远程启动时访问显示的方式设置 - 任何想法它是什么以及如何从远程 ssh-screen 会话中修改它,以便脚本可以访问windows吗?

Gil*_*il' 12

展示和权威

X 程序需要两条信息才能连接到 X 显示器。(请注意,这wmctrl是一个 X 程序,即使它访问其他进程的窗口而不是创建自己的窗口。)

  • 它需要显示的地址,通常是:0在您本地登录时或:10,:11等远程登录时(但数字可能会根据活动的 X 连接数而变化)。显示器的地址通常在DISPLAY环境变量中指示。

  • 它需要显示密码。X 显示密码称为魔术饼干。Magic cookie 没有直接指定:它们总是存储在 X 权限文件中,这些文件是“display :42has cookie 123456”形式的记录集合。X 权限文件通常在XAUTHORITY环境变量中指示。如果$XAUTHORITY未设置,程序将使用~/.Xauthority.

在屏幕会话中,环境变量在会话开始时确定,除非您在某个时候明确更改它们。因此,如果您在台式机上本地启动屏幕会话,然后远程连接到该会话,$DISPLAY并且$XAUTHORITY仍然指向您的台式机。但是,如果您从某个机器 C 到台式机的 ssh 连接启动屏幕会话,则不会设置变量。(如果您在 C 上有一个 X 服务器并通过 ssh 会话启用了 X 转发,则它们将被设置为指向 C。)

获取变量的值

据我了解,您正在尝试对桌面上显示的窗口进行操作。如果您是唯一使用台式机的人,则显示名称很可能是:0. 查找 X 权限文件的位置比较困难(在 Ubuntu 的默认设置下,它在一个随机生成名称的文件中)。

这里有一些方法来获得的价值DISPLAYXAUTHORITY

  • 简单的解决方案是始终从您的桌面启动屏幕会话,可能会在您的登录脚本中自动启动(来自~/.profile; 但只有在 X: test if 下登录时才这样做:测试是否DISPLAY设置为以开头的值:(应该涵盖所有情况'很可能会遇到))。在~/.profile

    case $DISPLAY in
      :*) screen -S local -d -m;;
    esac
    
    Run Code Online (Sandbox Code Playgroud)

    在 ssh 会话中:

    screen -d -r local
    
    Run Code Online (Sandbox Code Playgroud)
  • 你也可以保存的值DISPLAY,并XAUTHORITY在文件中调出值。在~/.profile

    case $DISPLAY in
      :*) export | grep -E ' (DISPLAY|XAUTHORITY)=' >~/.local-display-coordinates.sh;;
    esac
    
    Run Code Online (Sandbox Code Playgroud)

    在 ssh 会话中:

    . ~/.local-display-coordinates.sh
    screen
    
    Run Code Online (Sandbox Code Playgroud)
  • 您可以检测正在运行的进程的DISPLAY和的值XAUTHORITY。这更难自动化。您必须找出连接到您要处理的显示器的进程的 PID,然后从/proc/$pid/environ( eval export $(</proc/$pid/environ tr \\0 \\n | grep -E '^(DISPLAY|XAUTHORITY)=')¹)获取环境变量。

复制 cookie

另一种方法(按照Arrowmaster建议是不要尝试$XAUTHORITY在 ssh 会话中获取 的值,而是让 X 会话将其 cookie 复制到 中~/.Xauthority。由于每次登录时都会生成 cookie,如果您将陈旧的值保留在~/.Xauthority.

如果您的主目录可通过 NFS 或其他允许远程管理员查看其内容的网络文件系统访问,则可能存在安全问题。他们仍然需要以某种方式连接到您的机器,除非您启用了 X TCP 连接(Debian 默认关闭它们)。所以对于大多数人来说,这要么不适用(没有 NFS)要么不是问题(没有 X TCP 连接)。

要在登录桌面 X 会话时复制 cookie,请将以下行添加到~/.xprofile~/.profile(或登录时读取的其他脚本):

case :$DISPLAY:$XAUTHORITY in
  :*:?*) XAUTHORITY=~/.Xauthority xauth merge "$XAUTHORITY";;
esac
Run Code Online (Sandbox Code Playgroud)

然后在屏幕内部,您只需要setenv DISPLAY :0(或任何显示编号,但可能:0如上所述)。

¹ 原则上这缺乏正确的引用,但在这个特定的例子中$DISPLAY$XAUTHORITY不会包含任何 shell 元字符。


Ale*_*x R 6

如果你只想运行 1 个命令,你很可能会逃脱这个:

env DISPLAY=:0 XAUTHORITY=/home/UserOfDesktop/.Xauthority wmctrl -r "Firefox" -e 0,0,0,1920,1080
Run Code Online (Sandbox Code Playgroud)

确保将 DISPLAY=:0 更改为您要操作的桌面,并将 UserOfDesktop 更改为运行 X 会话的用户的名称。