在 Linux 安装中检查 WSL 版本(1 或 2)

在 Linux 安装中检查 WSL 版本(1 或 2)

您可以使用以下命令检查每个已安装的发行版的版本,

wsl -l -v

作为这个超级用户问题是

但是是否有可能从 Linux 安装内部知道 WSL 版本(1 或 2)?

是否有任何可靠的机制来检查版本?

我发现了什么?

环境和“互操作”

环境变量的唯一区别是 WSL 2 有一个名为WSL_INTEROP而版本 1 没有的变量。

该变量指向一个路径特殊文件。

内核版本

这篇reddit帖子回复积分使用以下命令,

uname -r | tr '[:upper:]' '[:lower:]'

WSL 1 输出:

4.4.0-19041-microsoft

WSL 2 输出:

5.4.72-microsoft-standard-wsl2

这可能是一个选择吗除了给出的答复,

最好不要进行内核检查,因为您可以构建和安装自己的内核,而有些人会将其删除。

虽然这个 askubuntu 接受了答案状态

如果内核版本 => 4.19,则是 WSL 版本 2。

还有其他选择/想法吗?

附录github/WSL repo 存在问题 #4555

答案1

在 WSL 中运行 WSL 将会起作用:

/mnt/c/Windows/System32/wsl.exe -l -v

输出不是 ascii,因此您可以转换然后在环境变量 WSL_DISTRO_NAME 上匹配:

/mnt/c/Windows/System32/wsl.exe -l -v | iconv -f unicode | dos2unix |grep $WSL_DISTRO_NAME | awk '{print $NF}'

您的安装可能需要进行一些其他字符转换。

编辑

如果运行多个类似名称的发行版,使用 egrep 会更可靠:

/mnt/c/Windows/System32/wsl.exe -l -v | iconv -f unicode | dos2unix |egrep "\b$WSL_DISTRO_NAME\s+Running" | awk '{print $NF}'

答案2

我认为我更喜欢 @DuncG 的答案。我认为它失败的唯一原因是如果Interop在 中被禁用/etc/wsl.conf。只要您确信互操作始终处于打开状态,这似乎是可行的方法。

但我要补充一点,WSL1 和 WSL2 之间存在相当多的差异,可以用作分类。


假设您正在使用 Windows 驱动器的自动安装:

  • mount | grep "/mnt/c" | grep -q drvfs对于 WSL1 返回成功,对于 WSL2 返回失败
  • mount | grep "/mnt/c" | grep -q 9p对于 WSL2 返回成功,对于 WSL1 返回失败

另外,lscpu但是默认情况下 Alpine 缺少此命令(当然,Ubuntu 和 Kali 上可用,我认为 Debian 上也可用):

  • lscpu | grep -q "Hypervisor vendor:.*Microsoft"将在 WSL2 上成功但在 WSL1 上失败,因为只有 WSL2 在 Hyper-V 下运行。

我对此不是 100% 确定,但在我测试的每种情况下(WSL1 和 WSL2 上的 Ubuntu 20.04、WSL1 和 WSL2 上的 Kali 以及 WSL1 和 WSL2 上的 Alpine):

  • /proc/cmdline在 WSL1 上BOOT_IMAGE=/kernel init=/init
  • /proc/cmdline在 WSL2 上initrd=\initrd.img panic=-1 pty.legacy_count=0 nr_cpus=16 (更新说明:最近发布的支持 Systemd 的 WSL2 版本对此略有改变。当然,使用.wslconfig设置内核命令行参数也会改变这一点。但是,下面的示例在上述任何一种情况下仍然有效。)

所以:

  • grep -q "^BOOT_IMAGE" /proc/cmdline在 WSL1 上返回成功,但在 WSL2 上返回错误
  • grep -q "^initrd" /proc/cmdline在 WSL2 上返回成功,但在 WSL1 上返回错误

我确信还有其他的,但如果你需要的话,这些是一些可能性。

相关内容