您可以使用以下命令检查每个已安装的发行版的版本,
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
这可能是一个选择吗除了给出的答复,
最好不要进行内核检查,因为您可以构建和安装自己的内核,而有些人会将其删除。
如果内核版本 => 4.19,则是 WSL 版本 2。
还有其他选择/想法吗?
答案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 上返回错误
我确信还有其他的,但如果你需要的话,这些是一些可能性。