在远程 X 显示器上打开一个窗口(为什么“无法打开显示器”)?

jus*_*ess 92 ssh cron x11

曾几何时,

DISPLAY=:0.0 totem /path/to/movie.avi
Run Code Online (Sandbox Code Playgroud)

从我的笔记本电脑 ssh 进入我的桌面后会导致图腾movie.avi在我的桌面上播放。

现在它给出了错误:

No protocol specified
Cannot open display:
Run Code Online (Sandbox Code Playgroud)

当两台计算机上都稳定时,我重新安装了 Debian 挤压,我想我破坏了配置。

我在谷歌上搜索过这个,但终其一生都无法弄清楚我应该做什么。

(VLC 有一个可以工作的 HTTP 接口,但不如 ssh 方便。)

当我尝试从 cron 作业运行它时,会出现同样的问题。

Gil*_*il' 89

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

展示和权威

X 程序需要两条信息才能连接到 X 显示器。

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

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

您正在尝试对桌面上显示的窗口进行操作。如果您是唯一使用台式机的人,则显示名称很可能是:0. 查找 X 权限文件的位置比较困难,因为在 Debian 挤压或 Ubuntu 10.04 下设置的 gdm 位于一个随机生成名称的文件中。(您之前没有问题,因为早期版本的 gdm 使用默认设置,即 cookie 存储在~/.Xauthority.)

获取变量的值

这里有一些方法来获得的价值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-setup.sh;;
    esac
    
    Run Code Online (Sandbox Code Playgroud)

    在 ssh 会话中:

    . ~/.local-display-setup.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
  :*:?*)
    # DISPLAY is set and points to a local display, and XAUTHORITY is
    # set, so merge the contents of `$XAUTHORITY` into ~/.Xauthority.
    XAUTHORITY=~/.Xauthority xauth merge "$XAUTHORITY";;
esac
Run Code Online (Sandbox Code Playgroud)

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

  • 一种自动化的方法是创建一个 `~/.xprofile`,它应该只在 X 登录期间运行,并让它使用正确的信息创建/更新 `~/.Xauthority`。一个符号链接就足够了吗? (2认同)
  • 从连接到显示器的现有进程中读取环境是出乎意料的,令人愉快的邪恶。我全心全意赞成。Unix.SE 为此需要 Evil Genius™ 徽章。 (2认同)

小智 21

我通过添加解决了这个问题

xhost +si:localuser:$USER
Run Code Online (Sandbox Code Playgroud)

~/.xprofile。我不知道这是否完全安全(我很想听听更有见识的人的想法),但我猜这比关闭访问控制(使用xhost +)要好得多,就像您通常建议的那样谷歌这个问题。