如何通过 shell 脚本检查环境是否为 WSL?

iro*_*and 11 bash ubuntu windows-subsystem-for-linux

在 中.bashrc,我有一些针对像这样的特定环境的配置。

if [ "$(uname)" = 'Linux' ]; then
   . "$HOME/.bash.d/ubuntu"
fi

if [ "$(uname)" = 'Darwin' ]; then
   . "$HOME/.bash.d/osx"
fi
Run Code Online (Sandbox Code Playgroud)

为了了解当前环境是否在WSL下,我使用/etc/wsl.conf通常只存在于 WSL 中的文件。

if [ -f "/etc/wsl.conf" ]; then
   . "$HOME/.bash.d/wsl"
fi
Run Code Online (Sandbox Code Playgroud)

当然,该文件也可以存在于其他环境中。

我应该如何检查当前环境是否在 WSL 中运行?

Not*_*1ds 21

没有“万无一失”的方法可以做到这一点,因为每种检测方法在某些情况下都可能导致误报或漏报。也就是说,如果您只是对个人配置文件执行此操作,那么您可能很清楚给定的方法是否适用于您的系统。

一些不同的方法,各有利弊:

  • 的存在/proc/sys/fs/binfmt_misc/WSLInterop很好地表明您处于 WSL 状态。这可能是最可靠的方法,Ubuntu 的 Snapd 项目就是采用这种方法作为其检测机制。默认情况下,该文件存在于 WSL1 和 WSL2 下。即使通过 禁用 Interop /etc/wsl.conf,该文件仍将由 WSL 在启动时创建。

    注意事项:当然,binfmt_misc可以使用名称 来设置条目WSLInterop,但这将是极其病态的,导致假阳性测试。

    此外,还可以覆盖 Interop 的名称,如我在此处询问 Ubuntu 的答案中所述。这将是一个不寻常的情况,但我们在修复错误时用它来暂时阻止 Snapd WSL 检测。当然,这会产生假阴性。

    在战争升级中,您可以通过 grep 查找该目录中的 来“阻止阻止” magic 4d5a,但这可能有点过头了;-)

  • 正如@MBehrens 提到的, WSL 下的默认内核名称包含字符串“Microsoft”(或“microsoft”,具体取决于版本)。使用uname -r/proc/version) 可以进行检测。

    注意事项:其他系统(我认为是 Azure)可能使用 Microsoft 构建的内核,这可能会产生误报。并且可以使用不同的名称为 WSL2 构建自定义内核,这会产生漏报。

  • 您甚至可以只检查环境变量$WSL_DISTRO_NAME。该变量会自动注入到 WSL 环境中。

    注意事项:您总是可以(病态地)在任何系统上创建此变量名称,从而导致误报。

    更重要的是,在某些情况下该变量不可,例如如果您su - $USER.

当然还有更多(例如,看看是否$(which powershell.exe)可执行),但是上面的内容应该让您对各种方法有所了解。


小智 9

检查输出

cat /proc/version
Run Code Online (Sandbox Code Playgroud)

cat /proc/sys/kernel/osrelease
Run Code Online (Sandbox Code Playgroud)

例如:

if [[ $(grep -i Microsoft /proc/version) ]]; then
echo "Bash is running on WSL"
fi
Run Code Online (Sandbox Code Playgroud)