为什么我的 X11 转发尝试失败并显示“connect /tmp/.X11-unix/X0:没有这样的文件或目录”?

为什么我的 X11 转发尝试失败并显示“connect /tmp/.X11-unix/X0:没有这样的文件或目录”?

在我的本地计算机上,我运行:

ssh -X [email protected]

(为了完整起见,我还使用 -Y 测试了以下所有内容,结果相同)。

正如预期的那样,这可以很好地访问remotemachine.com,并且一切看起来都很好。但是,如果我尝试运行 xcalc,我会得到:

 connect /tmp/.X11-unix/X0: No such file or directory
 Error: Can't open display: localhost:10.0

但,

$ ls -la /tmp/.X11-unix/
total 36
drwxrwxrwt 2 root root  4096 2012-11-23 09:29 .
drwxrwxrwt 8 root root 32768 2012-11-29 08:22 ..
srwxrwxrwx 1 root root     0 2012-11-23 09:29 X0

所以/tmp/.X11-unix/X0不仅存在,它还具有通用的r/w/x权限!

我以前使用过 x-forwarding 没有问题,尽管有一段时间没有......

服务器上的 uname -a 供参考:

Linux machinename 2.6.32-25-generic #45-Ubuntu SMP Sat Oct 16 19:52:42 UTC 2010 x86_64 GNU/Linux

在网上搜索了几个小时,但没有成功。其他人也提到了同样的问题,但没有解决方案。

答案1

我在使用 Cygwin 和 Xming 连接到远程 Linux 服务器时遇到了同样的问题。

我的 $DISPLAY 变量在 Cygwin 中只是“:0.0”,虽然它在本地工作,但它不适用于远程 ssh 命令。

在本地计算机上将变量更改为“localhost:0.0”解决了该问题。

export DISPLAY=localhost:0.0

一旦我这样做了,我的命令就起作用了:

ssh -Yf user@host gvim somefile.c

答案2

如果您有一个 X 服务器正在运行并且DISPLAY环境变量设置为:0,这会告诉应用程序使用 unix 域套接字连接到 X 服务器,该套接字通常可以在 Linux 上找到/tmp/.X11-unix/X0(尽管请参阅下面有关抽象命名空间在最近的 Linux 上)。

当你 ssh 到机器时远程机器sshd远程机器将 DISPLAY 设置为localhost:10(例如),这意味着 X 连接确实通过 TCP 完成到计算机本地主机的端口 6010。 sshd 开启远程机器监听那里的连接并将任何传入连接转发到 ssh 客户端。然后 ssh 客户端尝试连接/tmp/.X11-unix/X0(在本地端,而不是远程)以联系您的 X 服务器。

现在,也许您没有运行 X 服务器(您在 Mac 上吗?)或者可能在 /tmp/.X11-unix 中找不到 unix 域套接字,这意味着 ssh 在编译时尚未正确配置时间。

要找出 unix 套接字的正确路径,您可以strace -e connect xlogo在本地计算机上尝试(或系统上的等效路径)来查看正常的 X 应用程序的作用。

netstat -x | grep X也可能会提供线索。

作为记录,在 Linux Debian 机器上,Xorg 监听/tmp/.X11-unix/X0文件系统/tmp/.X11-unix/X0抽象命名空间(一般都写成@/tmp/.X11-unix/X0)。从 开始strace,X11 应用程序现在似乎默认使用该抽象名称空间,这解释了为什么那些在/tmp/.X11-unix删除后仍然可以工作,而不ssh使用该抽象名称空间。

答案3

这是对 Windows-Subsystem for Linux (WSL) 中特定信息的其他答案的补充。这接受的答案是正确的:您的DISPLAY变量配置不正确。然而,目前还不清楚为什么仅从这个答案来看会出现这种情况,所以我正在用这个答案进行补救。

如果您正在运行 cygwin 或适用于 Linux 的 Windows 子系统,并且您的 X11 服务器是基于 Windows 的(例如VcXsrv、 或XMing),则您的 X11 服务器更有可能侦听 TCP 端口(例如127.0.0.1端口6000-6010)而不是默认端口Unix 域套接字 ( /tmp/.X11-unix/X0)。目前,Unix 套接字在 Windows 上还没有得到很好的支持,甚至在 WSL 中也是如此。通过 IP 套接字,类 Linux 环境中的程序与直接在 Windows 主机上运行的程序之间进行通信通常也更容易。

当您在本地运行图形应用程序(即从主机的 Cygwin 或 WSL 环境),并且您的DISPLAY变量设置为默认值(即DISPLAY=:0.0)时,应用程序将首先尝试通过 Unix 套接字连接到 X 服务器/tmp/.X11-unix/X0。这将失败,但大多数应用程序将回退到 上的 TCP 连接localhost,假设您的 X 服务器配置为默认值,该连接应该会成功到达服务器。

connect()您可以通过在运行图形应用程序的 strace 日志中查找调用来确认是否发生了这种情况。这些通常会在应用程序的主窗口出现之前发生。

要点:当 ssh 从远程端重定向连接时,不会发生这种回退行为,因此您会收到该错误。sshd远程上的 确实会将 X11 连接转发到本地端,但 ssh 客户端的本地连接会终止,因为它无法通过 Unix 套接字连接到服务器。然后你就会收到ENOENT错误。它不会尝试与 TCP 本地主机的后备连接。

修复:在这种情况下,将DISPLAY变量更改为使用 TCP 语法而不是语法:0.0可以解决问题:

DISPLAY=127.0.0.1:0 ssh remote some-gui-application

就像其他答案提到的那样,您还可以从 shell 提示符中以交互方式导出该变量:

$ export DISPLAY=127.0.0.1:0
...
$ ssh remote some-gui-application

您还可以通过将该行添加到您的登录 shell 配置文件初始化脚本(例如~/.bash_profile)来更永久地存储此设置。

笔记:某些 shell 对于登录和非登录会话具有不同的初始化脚本。例如,使用 bash,您可以将该行写入非登录脚本,即~/.bashrc,而不是~/.bash_profile.如果这样做,请注意不要覆盖 ssh 可能设置的任何自定义值。如果您首先通过 ssh 跳入您的主机,然后再次跳入另一个主机(从而嵌套您的 X11 转发),就会出现这种情况。

答案4

我刚刚遇到了同样的问题。令人困惑的是,您会收到 no-such-file 错误偏僻的机,但实际上该文件在当地的(显示)机。

为了看看会发生什么,我在显示机器上手动创建了丢失的文件(实际上是 fifo),如下所示:

mkfifo /tmp/.X11-unix/X0

然后再次 ssh 到远程计算机,你瞧,X11 连接正常。

我不知道这是否相关,但我的显示机器不是 Linux,而是带有 cygwin 和 VcXsrv 的 Windows。 (远程机器是Linux)

相关内容