在 WSL2 之外看不到新定义的环境变量?

New defined environment varaibles can't be seen outside of WSL2?

在 WSL2 中,使用 ubuntu 发行版,我在 /etc/profile 中定义了一个新变量(我也尝试了 ~/.bashrc 和 /etc/environment)

export JDK_17_0=/home/scaventz/sdk/jdk-17

然后 source /etc/profile

然后我尝试通过使用 Intellij IDEA 在 Windows 中创建一个 Java 项目来获取此变量(该项目本身当然位于 WSL2 中):

public class Main {
    public static void main(String[] args) {
        String prop = "JDK_17_0";
        String jdk = System.getProperty(prop);
        if (jdk == null) {
            jdk = System.getenv(prop);
        }
        System.out.println(jdk);
    }
}

我得到一个空值。

这似乎是一个与 WSL2 相关的问题,有什么解决方法吗?

是的,这是意料之中的,是的,有一个解决方法。默认情况下,导出的 WSL 环境变量不会 back 传播到 Windows 环境。您可以通过(从 WSL/Bash 开始)看到相同的行为:

> export JDK_17_0=/home/scaventz/sdk/jdk-17
> powershell.exe
PS > $env:JDK_17_0

...这不会 return 任何东西。

但是 WSL 在 WSL 和 Windows 进程之间确实具有 sharing environment variables 的互操作功能。

重复我们之前的例子:

> export JDK_17_0=/home/scaventz/sdk/jdk-17
> WSLENV=JDK_17_0 powershell.exe
PS > $env:JDK_17_0
/home/scaventz/sdk/jdk-17

请注意,这并没有直接修改Windows中的系统环境变量;它只是将一个新变量注入 powershell.exe 进程。所以你应该能够通过调用 Intellij IDEA Windows 可执行文件来做同样的事情(你可能需要它的完整 /mnt/c/... 路径,如果它不在 Windows 路径中)以相同的方式。因为 Intellij 正在启动 Windows Java 可执行文件,所以为 Intellij 进程设置的环境变量应该传播到 Java 进程。

虽然我目前在这里没有那个特定的设置,但我至少能够通过从上面的 PowerShell 会话中启动 VSCode 来确认它。在 VSCode 中,环境变量仍然可用。

当然,还要注意 WSL/Linux 和 Windows 之间路径结构的差异。仅仅因为你可以在 Windows 上将 /home/scaventz/sdk/jdk-17 传递给 Java 运行 并不意味着它会理解它。 Java on Windows 理解 Windows 路径结构。它无法直接访问 /home/scaventz/sdk/jdk-17.

中的任何内容

我知道您并没有尝试访问该示例中的文件系统,但我认为这对您来说是未来的一步,因为您正在传递路径。因此,您可能希望对 WSLENV 使用 translatable path option

> export JDK_17_0=/home/scaventz/sdk/jdk-17
> WSLENV=JDK_17_0/p powershell.exe
PS > $env:JDK_17_0
\wsl$\Ubuntu\home\scaventz\sdk\jdk-17 # Or \wsl$\whatever_your_distribution_is_named\...

旁注:

It seems a WSL2 related issue

公平地说,不是真的。按照您描述事物的方式,如果您从 PowerShell 执行此操作,您会看到相同的行为。尝试在 PowerShell 中设置相同的环境变量,然后从 Windows 开始菜单启动 Intellij IDEA。它也无法访问该变量。

只有当从 父进程中启动新进程时,您才有希望将变量传递给该新进程。

除非你使用PowerShell修改系统变量。请注意,如果需要,您也可以通过 WSL 的 Interop with PowerShell 来做到这一点。