SSH 到 WSL 和 "Ubuntu" terminal/native 应用程序之间有什么不同?

what is different between SSH into WSL and the "Ubuntu" terminal/native app?

Win10、WSL2、Ubuntu 香草安装。我有一个 SSH 守护程序在 WSL2 实例中侦听(如果相关的话,在高编号端口上)。我只是注意到,在安装 VSCode/WSL 远程扩展后,如果我从 Ubuntu terminal/app/native 控制台中执行 code . (抱歉,我不知道这个叫什么)它 downloads/installs 是 VSCode 服务器的一个实例,至少目前看来 运行 正如我所期望的那样。

### launch the "Ubuntu" applet from the normal windows environment....
[lwobker:/dtop/scripts/jumpstamper]$ code .
Updating VS Code Server to version 899d46d82c4c95423fb7e10e68eba52050e30ba3
Removing previous installation...
Installing VS Code Server for x64 (899d46d82c4c95423fb7e10e68eba52050e30ba3)
Downloading:  66%

但是 - 如果我 ssh 进入 WSL 实例(作为同一用户)并再次键入 code . 那么它对我所说的一无所知,并且我得到标准的 Ubuntu “呃,抱歉,我不太清楚你的意思” 回复:

### SSH into the WSL2 virtual machine...
[lwobker:/dtop/scripts/fun]$ code .

Command 'code' not found, did you mean:

  command 'node' from deb nodejs (10.19.0~dfsg-3ubuntu1)
  command 'cde' from deb cde (0.1+git9-g551e54d-1.1build1)
  command 'cdde' from deb cdde (0.3.1-1build1)
  command 'tcode' from deb emboss (6.6.0+dfsg-7ubuntu2)
  command 'ode' from deb plotutils (2.6-10build1)

我本以为(显然是错误的)Ubuntu 终端与我使用 SSH 登录同一虚拟机的登录名相同 shell.. .但是...显然不是?

您将 运行 处理一些事情。

PATH 差异

首先,您现在 运行 所关注的是 $PATH 的不同之处。当您直接在终端主机上 运行 WSL 时,它会以相当“非正统”的方式启动您的 shell。至少,这与您 运行 在普通 Linux 主机上使用有很大不同。

“通常”,您会看到类似 login 的内容被调用来验证您的用户。 login(和 ssh)使用 PAM,即可插入认证模块系统来定义认证过程中发生的事情。其中一个常用的配置模块是pam_env,它可以改变环境。

您可以在 /etc/pam.d/login/etc/pam.d/sshd 中的 WSL/Ubuntu 中看到此定义。两者都包含以下行:

session    required     pam_env.so

您会在手册页中看到 pam_env 处理 /etc/environment,并且在 WSL 的 Ubuntu 20.04 上,定义为:

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"

这是 PATH 您在 ssh 进入您的 WSL 实例时应该看到的内容,以及在您的 shell 启动文件中所做的任何更改。

另一方面,您可能已经注意到,当您在本地启动 WSL 时,它实际上不需要登录。由于它 运行 与您的 Windows 帐户具有相同的权限,并且您已经登录到 Windows,因此在这里进行额外的身份验证真的没有意义。无论您使用哪个 WSL 用户,都是如此。

WSL 使用 /init 启动您的 shell,它是 PID1 初始化进程。 /init 负责设置紧密的 Windows 集成,包括(在 other things 中):

  • 将您的 Windows 路径附加到您的 WSL/Linux PATH
  • 设置允许您在 WSL/Linux.
  • 下启动 Windows .executables 所需的 Interop 文件

如果不清楚,这就是为什么当您通过 ssh 登录时找不到 code 的原因。由于 VSCode 是一个 Windows 可执行文件,并且在您的 Windows 路径中,只有当该路径由 /init。在 sshd 使用的 /etc/environment PATH 而不是

Windows
中的远程 GUI

但实际上,即使将它添加到路径中也无济于事。

我不确定您尝试通过 SSH 运行 VSCode 的确切用例,但请注意 运行ning Windows 通过 SSH 的 GUI 应用程序与 Linux 上的 X 转发有很大不同。确实没有一对一的等价物。

默认情况下,即使您提供 Windows 可执行文件的完整路径,它也不会通过 SSH 执行。这是意料之中的。即使 Windows OpenSSH 服务器也有此问题,因为它 运行 作为服务,并且服务没有 GUI 访问权限。有关详细信息,请参阅 this question

我不确定是否有办法让 GUI 通过 WSL 显示在远程主机上。我认为这不太可能,而且无论如何都不值得。

我能看到的最佳方案是使用 Windows OpenSSH 运行ning 作为普通用户,如上一个问题中所述。然后,一旦登录到您的 Windows 用户,就会出现 运行 wsl。然后,您可能能够在 SSH 主机本身上启动 GUI 客户端。

远程VSCode

您可能想要做的是首先通过VSCode远程访问您的 WSL 实例。

至少有三种支持的解决方案:

  • 远程桌面协议

    假设您有 Windows Pro 或更高版本,您可以从任何支持 RDP 的客户端轻松访问主机桌面,包括 WSL 和 VSCode。

  • VSCode 的“远程 - SSH”扩展

    安装“Remote - SSH”扩展或“远程开发”扩展包,将允许您直接从 VSCode 中打开任何 SSH 实例,包括浏览文件系统和调试。它的工作方式与您在 WSL 中看到的相同,它在您的 Linux 实例中设置一个服务器,然后通过 SSH 与之通信。

  • 运行 Linux 版本的 VSCode 并将其转发给 ssh 客户端

    这可能是我最不喜欢的选项,只是因为其他两个要好得多,但是您始终可以将 VSCode 的 Linux 版本安装到 WSL/Ubuntu 中,远程 SSH ,并将 X 客户端转发到与 SSH 客户端位于同一台计算机上的 X 主机 运行ning。

    当然,如果您通过 SSH 连接的机器是 Windows 主机,您仍然需要一个 X 服务器。在 Windows 10 上,您需要第三方 X 服务器,但在 Windows 11 上,您可以为此使用 WSLg。

    当然,此解决方案不限于 VSCode。任何 Linux 编辑器或 IDE 都可以这样使用。