【问题标题】:Xt error: Can't open display, if using default DISPLAYXt 错误:无法打开显示,如果使用默认显示
【发布时间】:2016-10-16 00:24:47
【问题描述】:

概述

我正在尝试让 XQuartz 在 OSX 上工作,这样我就可以通过 Docker 进行 X11 转发。我正在关注the instructions here。我相信我的问题可能只由第一部分回答,但为了以防万一(为了避免 XY 问题),我也提供了第二部分。

安装

我已经通过自制软件、brew cask install xquartz 安装了它。然后我open -a XQuartz 启动它。

本地 xterms

测试一下,如果我尝试打开xterm,它不起作用:

MacBook-Pro:opencv-gui csaftoiu$ xterm
xterm: Xt error: Can't open display: /private/tmp/com.apple.launchd.3wncZULdXC/org.macosforge.xquartz:0

虽然伪文件存在:

MacBook-Pro:opencv-gui csaftoiu$ echo $DISPLAY
/private/tmp/com.apple.launchd.3wncZULdXC/org.macosforge.xquartz:0
MacBook-Pro:opencv-gui csaftoiu$ ls -alh $DISPLAY
srw-rw-rw-  1 csaftoiu  wheel     0B May  6 21:12 /private/tmp/com.apple.launchd.3wncZULdXC/org.macosforge.xquartz:0

我可以通过 XQuartz 打开一个 xterm。那么:

bash-3.2$ echo $DISPLAY
:0

此值也适用于常规 OSX:

$ DISPLAY=:0 xterm
# opens xterm, waits for it to finish
$

以下不起作用,不知道为什么基于the answer here:

xterm: Xt error: Can't open display: localhost:0
MacBook-Pro:opencv-gui csaftoiu$ DISPLAY=127.0.0.1:0 xterm
xterm: Xt error: Can't open display: 127.0.0.1:0
MacBook-Pro:opencv-gui csaftoiu$ DISPLAY=`ipconfig getifaddr en0`:0 xterm
xterm: Xt error: Can't open display: 192.168.1.15:0

请注意,xinit 出于某种原因确实有效:

$ xinit

xinit: XFree86_VT property unexpectedly has 0 items instead of 1
# opens xterm, waits for it to finish
xinit: connection to X server lost

waiting for X server to shut down

问题 1:XQuartz 实际监听的是什么?


使用 socat 进行 Docker 转发

无论如何,继续前进,这个socat 命令不起作用:

MacBook-Pro:opencv-gui csaftoiu$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"

从另一个窗口运行它:

MacBook-Pro:opencv-gui csaftoiu$ docker run --rm -it -e DISPLAY=`ipconfig getifaddr en0`:0 ubuntu:14.04 bash
root@912eec31b8cb:/# apt-get update && apt-get install xterm
... such install, wow ...
root@912eec31b8cb:/# xterm
Warning: This program is an suid-root program or is being run by the root user.
The full text of the error or warning message cannot be safely formatted
in this environment. You may get a more descriptive message by running the
program as a non-root user or by removing the suid bit on the executable.
xterm: Xt error: Can't open display: %s
root@912eec31b8cb:/# echo $DISPLAY
192.168.1.15:0

从socat 窗口我得到:

2016/06/14 21:08:15 socat[24289] E connect(5, LEN=68 AF=1 "/private/tmp/com.apple.launchd.3wncZULdXC/org.macosforge.xquartz:0", 68): Connection refused

我也不能使用有效的 DISPLAY 变量:

MacBook-Pro:opencv-gui csaftoiu$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\":0\"
2016/06/14 21:09:43 socat[24309] E connect(5, LEN=4 AF=1 ":0", 4): No such file or directory

现在,这不是 UNIX 客户端 IP。但是,我不知道 什么 DISPLAY=:0 正在连接。它肯定不是端口 6000,因为那是它曾经监听的端口。如果我把它改成6005,转发到6000,让Docker容器DISPLAY改为$(ipconfig getifaddr en0):5,那么连接当然会被拒绝:

$ socat TCP-LISTEN:6005,reuseaddr,fork TCP:localhost:6000
2016/06/14 21:20:32 socat[25379] E connect(8, LEN=16 AF=2 127.0.0.1:6000, 16): Connection refused

问题2:如何从这里着手?

【问题讨论】:

    标签: macos docker x11 x11-forwarding xquartz


    【解决方案1】:

    我重新安装 XQuartz 后没有重新启动。我重新启动,现在它可以工作了。 :)。

    【讨论】:

    • 我遵循的说明确实说要注销并重新登录以使 xQuarts 工作,我照做了。重新启动也是我错过的关键部分,谢谢!
    【解决方案2】:

    我需要退出终端,然后重新启动它才能让它工作。

    【讨论】:

    • 终端需要查看安装了 X 的新路径。您可以在命令行中添加它,但重新启动终端可以轻松解决。
    【解决方案3】:

    对于 OS X 10.6.3 及更高版本,根据XQuartz 2.7.11 instructions:

    如果这是您第一次安装 XQuartz,您可能希望退出并重新登录。这将更新您的 DISPLAY 环境变量以指向 XQuartz.app 而不是 X11.app。如果您希望继续使用 X11.app 作为默认服务器(您仍然可以手动启动 XQuartz.app),您需要使用 launchctl(1) 禁用 /Library/LaunchAgents/org.macosforge.xquartz.startx.plist。

    在我的 macOS High Sierra 上安装 XQuartz 2.7.11 后,退出我的 Mac 并再次登录就足以通过我的 MacOS 终端运行。但是,您可以通过打开 XQuartz Terminal 应用程序(XQuartz > Applications > Terminal)并从那里运行您的 X 应用程序来避免注销和登录。例如:

    然后

    bash-3.2$ xclock &
    

    【讨论】:

    • > 如果这是您第一次安装 XQuartz,您可能希望退出并重新登录 谢谢!!!!
    【解决方案4】:

    Docker for Desktop MacOS 2018+ 中的 Dockerized UI 应用程序。于 2021 年更新。

    历经千辛万苦,得到最简单的版本,不依赖于检查端口、IP 等......就是这样。

    • 运行版XQuartz 2.7.11 (xorg-server 1.18.4)
    • Docker版本docker version 18.06.1-ce

    确保安装 XQuartz(更新为 2021 change)

    $ brew install socat
    $ brew install --cask xquartz
    
    • 不要忘记关闭注销并重新登录。

    注意:此时,请确保重新启动您的主机(例如 MacOS)。以下错误与您不这样做有关:E connect(5, LEN=2 AF=1 "<anon>", 2): Invalid argument

    $ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
    2021/04/04 17:28:58 socat[40606] E connect(5, LEN=2 AF=1 "<anon>", 2): Invalid argument
    

    说明

    • 您需要打开 2 个终端:一个用于带显示的 socat,另一个用于运行 UI 容器。

    1。关闭任何 6000

    在新终端上,验证端口 6000 上是否有任何东西在运行

    $ lsof -i TCP:6000
    $
    

    如果有什么,直接杀掉进程

    2。关闭任何 6000

    在该端口上打开一个套接字并保持终端打开

    $ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
    

    3。验证 6000 是否打开

    在新的终端中,验证是否打开

    $ lsof -i TCP:6000
    COMMAND   PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
    socat   29298 marcellodesales    5u  IPv4 0xe21e43ca9d99bf1d      0t0  TCP *:6000 (LISTEN)
    

    4。构建并运行简单的 UI 应用

    $ cat Dockerfile.eyes
    
    FROM debian:latest
    RUN apt-get update && apt-get install -y x11-apps
    RUN rm -rf /tmp/* /usr/share/doc/* /usr/share/info/* /var/tmp/*
    RUN useradd -ms /bin/bash user
    ENV DISPLAY :0
    USER user
    ENTRYPOINT ["/bin/sh", "-c", "$0 \"$@\"", "xeyes"]
    
    $ docker build -t eyes -f Dockerfile.eyes .
    

    使用 Docker 中的变量会发生奇迹。只需使用 -e DISPLAY=docker.for.mac.host.internal:0 就可以了,因为它将指向内部 IP 地址并将其提供给 docker 映像。港口前锋会发挥它的魔力。

    $ docker run -ti --rm -e DISPLAY=docker.for.mac.host.internal:0 eyes
    

    我注意到此时 XQuartz 已自行打开到同一个端口

    $ lsof -i TCP:6000
    COMMAND   PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
    socat   29298 marcellodesales    5u  IPv4 0xe21e43ca9d99bf1d      0t0  TCP *:6000 (LISTEN)
    X11.bin 29462 marcellodesales    8u  IPv6 0xe21e43ca7cdb1135      0t0  TCP *:6000 (LISTEN)
    

    5。获利并运行更多应用程序

    $ docker run -e DISPLAY=docker.for.mac.host.internal:0 jess/tor-browser
    

    $ docker run -e DISPLAY=docker.for.mac.host.internal:0 batmat/docker-eclipse
    

    【讨论】:

    • 这看起来很有希望,但结果 GUI 会话不稳定(在 30 秒内关闭,没有错误消息。我读过有人可以在某处使用 -t 标志以某种方式禁用默认超时,但文档很少在 socat 上并在 socat TCP-LISTEN 命令中添加 't ignoreof' 肯定不起作用(事实上,即使在图形应用程序关闭后,socat 也会继续侦听端口 6000)。我也收到 libGL 错误:没有匹配fbConfigs or visuals found libGL error: failed to load driver: swrast
    【解决方案5】:

    我用这个代码会帮助你在macos Big sur https://apple.stackexchange.com/questions/411619/how-to-make-dia-which-uses-x11-xquartz-work

    export DISPLAY=:0 # 修复“无法打开显示”。 export LANG="en_US.UTF-8" # 修复恼人的 Xterm 窗口打开。

    exec "$CWD/dia-bin" --integrated

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    相关资源
    最近更新 更多