WSL Ubuntu:无法启动终结者

WSL Ubuntu:无法启动终结者

我在 Windows 10 上安装了 WSL Ubuntu 20.04。我还安装了 VcXsrv(Xlaunch)。我使用以下命令启动 VcXsrv:

 "C:\Program Files\VcXsrv\vcxsrv.exe" :0 -ac -terminate -lesspointer -multiwindow -clipboard -wgl -dpi auto 

在 Ubuntu 终端上,我无法启动终结器。请帮忙。

$ export DISPLAY=0:0
$ terminator
Unable to init server: Could not connect: Connection refused
Unable to init server: Could not connect: Connection refused
You need to run terminator in an X environment. Make sure $DISPLAY is properly set.

以下是 netstat 的输出

C:\Windows\system32>netstat -abno|findstr 6000
  TCP    0.0.0.0:6000           0.0.0.0:0              LISTENING       42548
  TCP    127.0.0.1:6000         127.0.0.1:65381        ESTABLISHED     42548
  TCP    127.0.0.1:6000         127.0.0.1:65382        ESTABLISHED     42548
  TCP    127.0.0.1:6000         127.0.0.1:65383        ESTABLISHED     42548
  TCP    127.0.0.1:65381        127.0.0.1:6000         ESTABLISHED     42548
  TCP    127.0.0.1:65382        127.0.0.1:6000         ESTABLISHED     42548
  TCP    127.0.0.1:65383        127.0.0.1:6000         ESTABLISHED     42548
  TCP    [::]:6000              [::]:0                 LISTENING       42548
 Get-NetFirewallApplicationFilter |? { $_.Program -like "*vcxsrv*" } | Get-NetFirewallRule


Name                          : TCP Query User{81BBD37C-DC9F-4C50-B2C6-A1B58CABD66C}C:\program files\vcxsrv\vcxsrv.exe
DisplayName                   : VcXsrv windows xserver
Description                   : VcXsrv windows xserver
DisplayGroup                  :
Group                         :
Enabled                       : True
Profile                       : Domain
Platform                      : {}
Direction                     : Inbound
Action                        : Allow
EdgeTraversalPolicy           : DeferToUser
LooseSourceMapping            : False
LocalOnlyMapping              : False
Owner                         :
PrimaryStatus                 : OK
Status                        : The rule was parsed successfully from the store. (65536)
EnforcementStatus             : NotApplicable
PolicyStoreSource             : PersistentStore
PolicyStoreSourceType         : Local
RemoteDynamicKeywordAddresses :

Name                          : {14B2C126-9C6A-42CA-B496-62F2D88ED067}
DisplayName                   : VcXsrv windows xserver
Description                   : VcXsrv windows xserver
DisplayGroup                  :
Group                         :
Enabled                       : True
Profile                       : Public
Platform                      : {}
Direction                     : Inbound
Action                        : Block
EdgeTraversalPolicy           : Block
LooseSourceMapping            : False
LocalOnlyMapping              : False
Owner                         :
PrimaryStatus                 : OK
Status                        : The rule was parsed successfully from the store. (65536)
EnforcementStatus             : NotApplicable
PolicyStoreSource             : PersistentStore
PolicyStoreSourceType         : Local
RemoteDynamicKeywordAddresses :

Name                          : UDP Query User{87720067-4851-485C-A9B1-ABE74E6BE131}C:\program files\vcxsrv\vcxsrv.exe
DisplayName                   : VcXsrv windows xserver
Description                   : VcXsrv windows xserver
DisplayGroup                  :
Group                         :
Enabled                       : True
Profile                       : Domain
Platform                      : {}
Direction                     : Inbound
Action                        : Allow
EdgeTraversalPolicy           : DeferToUser
LooseSourceMapping            : False
LocalOnlyMapping              : False
Owner                         :
PrimaryStatus                 : OK
Status                        : The rule was parsed successfully from the store. (65536)
EnforcementStatus             : NotApplicable
PolicyStoreSource             : PersistentStore
PolicyStoreSourceType         : Local
RemoteDynamicKeywordAddresses :

Name                          : {1B4ABAF3-28C3-42F8-8C62-3AE54EFFC97C}
DisplayName                   : VcXsrv windows xserver
Description                   : VcXsrv windows xserver
DisplayGroup                  :
Group                         :
Enabled                       : True
Profile                       : Public
Platform                      : {}
Direction                     : Inbound
Action                        : Block
EdgeTraversalPolicy           : Block
LooseSourceMapping            : False
LocalOnlyMapping              : False
Owner                         :
PrimaryStatus                 : OK
Status                        : The rule was parsed successfully from the store. (65536)
EnforcementStatus             : NotApplicable
PolicyStoreSource             : PersistentStore
PolicyStoreSourceType         : Local
RemoteDynamicKeywordAddresses :

答案1

我最初投票关闭此帖子,因为它重复了一般如何使用适用于 Linux 的 Windows 子系统运行 GUI 应用程序但实际情况有些不同。

我们确实没有通用的,“我如何确定DISPLAYWSL 的正确变量?”问题由于我们最终在评论中对此进行了故障排除,因此让我在答案中介绍一下这里的各种选项。

首先,一些“搜索词”。在 WSL 中尝试运行 Linux GUI 应用程序时,您可能会遇到不同的错误:

  • Error: Unable to open display
  • Error E233: cannot open display
  • Error: (SDL_Init) No available video device(来自 SDL 应用程序)
  • Error: An OpenGL context could not be created

首先,请阅读如何使用适用于 Linux 的 Windows 子系统运行 GUI 应用程序。您需要选择其中一种解决方案才能在 WSL 中运行 Linux GUI 应用程序。

但如果您仍然遇到问题,那么您可能需要采取额外措施。

WSL2:带有 WSLg 的 Windows 11

如果您将 Windows 11 与 WSLg(在 Windows 11 中运行 Linux GUI 应用程序的默认 WSL 选项)一起使用,则DISPLAYWSL 应该为您设置变量。它应该是:

$ echo $DISPLAY
:0

这相当于DISPLAY=localhost:0,因为 WSLg 在 WSL2 VM 内部运行,所以它对于您的 WSL 会话来说是“本地的”。

防火墙规则也应自动为您设置。

你应该:

$ echo $WAYLAND_DISPLAY
wayland-0

用于运行 Wayland 应用程序(X 的后继者)。

如果这些变量未正确设置:

  • 检查您的启动配置文件,看看您(或您安装的应用程序)是否将其设置DISPLAY为其他内容。

    尝试启动 WSL(从 PowerShell),而不运行 Bash 启动:

    wsl ~ -e bash --noprofile --norc
    

    然后再次检查变量。如果它们现在正确,那么某物启动时更改了它们。您需要编辑启动配置,找到罪魁祸首并修复它。

  • 您是否正在运行 Systemd 启用脚本?如果是,请尝试不使用它。默认情况下,Systemd 环境没有DISPLAY(和其他内置 WSL 变量)。大多数 Systemd 启用脚本都会尝试处理这个问题,但它可能会遇到意想不到的极端情况。

WSL1:带有第三方 X 服务器的 Windows 10 或 11

当在 WSL1 中使用第三方 X 服务器(如 VcXsrv)(如此处的原始问题所示)时,应该DISPLAY再次为:0,与上面的 WSLg 一样。

$ echo $DISPLAY
:0

WSL1 运行在同一网络中作为 Windows 主机,因此 VcXsrv(等)将是当地的到 WSL1。

使用第三方 Windows X 服务器运行 WSL1 时不需要特殊的防火墙规则。

WSL2:带有第三方 X 服务器的 Windows 10 或 11

这是最复杂的情​​况,也是原始问题所涵盖的情况。您至少需要两件事才能在 WSL2 下与 VcXsrv(等)进行通信:

  • 变量的正确 IP 地址DISPLAY
  • 允许访问的防火墙规则

这两者都是必需的,因为 WSL2 在独立网络比 Windows 主机更安全。它使用虚拟交换机后面的虚拟网络接口运行,该虚拟交换机已进行 NAT。因此,localhost:0(或简称:0)指的是WSL2网络接口,不是Windows 主机。

在默认的 WSL2 配置中,DNS 解析器(由 WSL)设置为 Windows 主机,使用该虚拟交换机的 IP 地址。因此,您可以尝试多种选项来确定正确的 IP DISPLAY

  • export DISPLAY="$(hostname).local:0"

    这使用了 mDNS,该功能在过去几年中已在 WSL2 中提供。请参阅Stack Overflow 上的这个答案了解更多信息。这确实要求使用默认解析器。

  • export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0

    这将解析/etc/resolv.conf以获取解析器正在运行的 Windows 主机的 IP 地址。同样,这需要使用默认的 WSL2 解析器。

  • export DISPLAY=$(host主机名--long| grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r')

    如果以上两个选项不起作用,那么(信用这个 Ask Ubuntu 答案,则此选项将尝试获取基本的网络接口。通常这是一个私有网络地址,如192.168.1.10010.0.1.5

    如果这个地址是静态的,你可以简单地对其进行硬编码,这对 OP 有效:

    export DISPLAY=192.168.1.100:0` # Adjust with your actual IP
    

    如果它是动态分配的并且经常更改,那么您可以使用上述命令尝试获取它。但是,请注意,这是很多比其他任何方法都慢。在我相对较快的系统上,大约需要 3 秒钟才能完成。

防火墙规则

当将 WSL2 与第三方 X 服务器一起使用时,您还需要确保防火墙允许从 WSL2 访问 Windows 主机。

首次尝试连接到 X 服务器时,Windows Defender应该显示一个对话框,您可以在其中允许从公共和/或私有网络进行访问。不幸的是,WSL2 网络在 Windows 主机中被视为“公共”,因此您需要确保选择了公共。

注意:根据我的经验,对话框经常出现在后面其他窗口,很容易被忽略。如果发生这种情况,并且关闭该对话框而不允许流量,则可能会设置“拒绝”规则。

但是,此处的公共“允许”规则还意味着防火墙将允许其他公共网络(如公共 wifi 网络)上该端口的流量。如果您在不在家中的网络上运行 X 服务器,这可能会带来安全风险。

首先,确保规则到位允许至少可以访问。从管理 PowerShell 会话中:

Get-NetFirewallApplicationFilter |? { $_.Program -like "*vcxsrv*" } | Get-NetFirewallRule

调整-like你的 X 服务器的可执行文件的选项。

此时,最简单的方法可能是DisplayName在输出中查找。然后运行Windows Defender 防火墙从开始菜单,找到关联规则入境规则. 确保(至少)公共网络有“允许”规则。

这个答案有点长,添加有关将防火墙规则限制为来自 WSL2(而不是其他公共网络)的流量的信息可能有点超出范围。如果有人对如何做到这一点感兴趣,请就该特定主题发布单独的问题。

相关内容