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

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

曾几何时,

DISPLAY=:0.0 totem /path/to/movie.avi

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

现在它给出了错误:

No protocol specified
Cannot open display:

当 Debian squeeze 在两台计算机上都稳定后,我重新安装了它,我想我破坏了配置。

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

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

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

答案1

(改编自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 squeeze 或 Ubuntu 10.04 下设置的 gdm 中,它位于一个具有随机生成名称的文件中。 (之前没有问题,因为早期版本的 gdm 使用默认设置,即存储在~/.Xauthority. 中的 cookie。)

获取变量的值

以下是获取DISPLAY和 的值的几种方法XAUTHORITY

  • 您可以从桌面系统地启动屏幕会话,也许会在登录脚本中自动启动(来自~/.profile; 但只有在 X: test if 下登录时才执行此操作,如果DISPLAY设置为以以下开头的值:(这应该涵盖您可能遇到的所有情况)遇到))。在~/.profile

    case $DISPLAY in
      :*) screen -S local -d -m;;
    esac
    

    然后,在 ssh 会话中:

    screen -d -r local
    
  • DISPLAY您还可以将和的值保存XAUTHORITY在文件中并调用这些值。在~/.profile

    case $DISPLAY in
      :*) export | grep -E '(^| )(DISPLAY|XAUTHORITY)=' >~/.local-display-setup.sh;;
    esac
    

    在 ssh 会话中:

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

复制cookies

另一种方法(按照建议箭王) 的目的是不尝试获取 ssh 会话中的值$XAUTHORITY,而是让 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

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

答案2

通过添加解决:

xhost +si:localuser:$USER

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

答案3

对我有用,debian wheezy -> ubuntu 值得信赖。

注意:在这种情况下,服务器不运行显示管理器,它是一个“无头”虚拟机,没有连接显卡或显示器。

bob@laptop:~$ grep -iB 1 tcp /etc/gdm3/daemon.conf
[security]
DisallowTCP = false
bob@laptop:~$ ssh -C -R 6000:127.0.0.1:6000 alice@server
X11 forwarding request failed on channel 0
alice@server:~$ export DISPLAY=:0.0
alice@server:~$ xterm

笔记本电脑上的 X 显示显示服务器上运行的 xterm 的输出。

调试使用:

bob@laptop:~/tmp$ nc -v 127.0.0.1 6001
localhost [127.0.0.1] 6001 (x11-1) : Connection refused
bob@laptop:~/tmp$ nc -v 127.0.0.1 6000
localhost [127.0.0.1] 6000 (x11) open
alice@server:~$ nc -v 127.0.0.1 6000
Connection to 127.0.0.1 6000 port [tcp/x11] succeeded!*
alice@server:~$ strace xterm

strace会泄露大量关于它正在做什么的血淋淋的细节,你应该能够猜测它卡在哪里 - 等待连接或其他什么。

在一行..

ssh -C -R 6000:127.0.0.1:6000 alice@server "DISPLAY=:0.0 xterm"

相关内容