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


81

很久以前,

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

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

现在,它给出了错误:

No protocol specified
Cannot open display:

当两台计算机都稳定下来时,我重新安装了Debian squeeze,我想我打破了配置。

我已经用谷歌搜索了,无法终生弄清楚我应该做的事情。

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

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


1
远程计算机是否显示.Xauthority文件?另一个明显的问题是-您的ssh服务器和客户端是否配置为允许X转发?您用于ssh的命令是什么?
Faheem Mitha

1
我要转发X吗?我希望命令在主机而不是客户端上执行。我的ssh命令只是ssh me @ host在主机上找不到.Xauthority与任何文件都不匹配。
贾斯汀·水芹,

正如Faheem所建议的那样,有一个很好的变化,那就是您的问题是由于totem找不到X cookie,而您需要将其设置XAUTHORITY为适当的值,即,您在桌面上的常规会话中的值。阅读Linux:通过ssh + screen发起会话进行某些背景操作时,wmctrl无法打开显示;还可以查看相关答案。作为超级用户,我可以在另一个用户桌面上启动图形程序吗?
Gilles

1
好吧,实际上坐在计算机上并键入echo $ XAUTHORITY在ssh会话中提供了/ var / run / gdm3 / auth-for-jcress-bb32gX / database,键入echo $ DISPLAY =(上面的路径)不能解决问题
贾斯汀水芹

1
我责怪GDM3,为什么不能他们刚刚一直$XAUTHORITY~/.Xauthority像大家期待的那样。
Arrowmaster 2011年

Answers:


78

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

显示和权限

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

  • 它需要的显示,这是典型的地址:0,当你在本地登录或:10:11等等。当你在远程登录(但数量取决于有多少X连接有效改变)。显示器的地址通常在DISPLAY环境变量中指示。

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

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

获取变量的值

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

  • 您可以从桌面上系统地启动屏幕会话,也许会自动在登录脚本中(从~/.profile;开始;但是仅当在X:下登录时才执行此操作:测试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/environeval 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

¹ 原则上,它缺少适当的引号,但在此特定情况下$DISPLAY$XAUTHORITY将不包含任何shell元字符。


2
自动执行此操作的一种方法是创建一个~/.xprofile仅在X登录期间运行的,并~/.Xauthority使用正确的信息创建/更新它。一个符号链接就足够了吗?
Arrowmaster 2011年

@Arrowmaster:这是一个很好的建议。我没想到 它不能在所有情况下都起作用,例如,如果您登录了多个X会话(在不同的终端上,使用vnc等),但是它很简单,对于典型的使用来说已经足够了。符号链接是最好的方法。嗯,实际上有一个更好,更简单的方法:您可以信息复制到中~/.Xauthority
吉尔斯

1
将东西放在像xauth extract - $DISPLAY | xauth -f "$HOME/.Xauthority" merge -~/.xprofile解决多$ DISPLAY的情况?
Arrowmaster 2011年

@Arrowmaster:您在多个显示器上看到什么问题?虽然您的代码从原则上讲可能更简洁一些,因为您仅提取有关您感兴趣的显示的信息,但是在请求者的情况下进行简单合并,或者在非常特殊的情况下,我都不会发现任何错误。
Gilles

1
从连接到显示器的现有过程中读取环境是令人意外的恶果。我全力以赴。Unix.SE为此需要Evil Genius™徽章。
derobert

19

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

xhost +si:localuser:$USER

~/.xprofile。我不知道这是否完全安全(我会很感兴趣听到更多知识渊博的人们的想法),但是我想这比关闭访问控制(使用xhost +)要好得多,如您建议的那样google这个问题。


1
localuser服务器解释的地址是完全安全的。默认情况下,Debian甚至在登录过程中(在中/etc/X11/Xsession.d/35x11-common_xhost-local)执行此操作。有关更多详细信息,请参见Xsecurity手册页
山姆·莫里斯

如果您在局域网上,xhost +在大多数情况下可能就足够了
Alexis Wilke

您能否解释此命令的含义?
alpha_989

@ alpha_989:这表示“授予对以我[$ USER]身份运行的任何本地运行的[localuser]应用程序的访问权限。” “ si”只是胶水(请参阅xhost(1)Xsecurity(7)文档)。就其本身而言,该命令也不会允许任何形式的远程访问或X11转发(的量,“神奇的cookie”机制通常是优选的过xhost)。
凯文

7

你需要 export DISPLAY=:0.0


不。当变量写在同一行上时,Unix不需要导出。该变量在行结束之前一直有效。
Alexis Wilke

确实,你是对的。
asoundmove,2016年

这个答案显然是错误的,应该删除。
Piotr Dobrogost

不知道只要输入DISPLAY =:0.0就能设置变量名。谢谢@asoundmove。但是,我认为:0.0是服务器显示上DISPLAY变量的值。如果从Putty登录,则变量DISPLAY应该为10或更高。因此应该为DISPLAY =:10
alpha_989 '17

3

为我工作,debian wheezy-> ubuntu trusty。

注意:在这种情况下,服务器没有运行显示管理器,它是没有图形卡或监视器的“无头”虚拟机。

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"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.