44

非常简单,找出您所使用的操作系统的常用位置似乎与 Ubuntu for Windows 上的普通 Ubuntu 相同。例如uname -a,与原生 GNU/Linux 安装/etc/os-version相同,与 Ubuntu Trusty Tahr 安装相同。

我唯一能想到的就是检查是否/mnt/c/Windows存在,但我不确定这是否是一个万无一失的想法。

4

14 回答 14

46

以下内容适用于 Windows 10、macOS 和 Linux 上的 bash:

#!/bin/bash
set -e
if grep -qEi "(Microsoft|WSL)" /proc/version &> /dev/null ; then
    echo "Windows 10 Bash"
else
    echo "Anything else"
fi

您需要根据WSL 开发人员 Ben Hillis 的评论检查“Microsoft”和“WSL” :

就目前而言,这可能是最好的方法。我不能保证我们永远不会更改这些 ProcFs 文件的内容,但我认为我们不太可能将其更改为不包含“Microsoft”或“WSL”的内容。

/proc/sys/kernel/osrelease
/proc/version

并且大小写应被忽略grep。在 WSL2 中,/proc/version给出小写的 microsoft。

于 2017-04-25T18:46:53.177 回答
20

@per-lundberg 更新答案:

if [[ -n "$IS_WSL" || -n "$WSL_DISTRO_NAME" ]]; then
    echo "This is WSL"
else
    echo "This is not WSL"
fi

注意:IS_WSL存在于旧版本中(使用lxrun),而WSL_DISTRO_NAME存在于当前版本中(来自 Microsoft Store)。

于 2020-04-04T23:59:17.777 回答
9

我也一直在寻找检测方法。到目前为止,我已经找到了 2 个。

  • /proc/sys/kernel/osrelease是“3.4.0-微软”

  • /proc/version是“Linux 版本 3.4.0-Microsoft (Microsoft@Microsoft.com) (gcc 版本 4.7 (GCC)) #1 SMP PREEMPT Wed Dec 31 14:42:53 PST 2014”

如果您只使用默认安装的 Ubuntu 发行版,那么使用它们应该没有问题,因为他们说他们不太可能将其设置为不包含 "Microsoft" 或 "WSL" 的东西

但是,如果您要安装不同的 Linux 发行版,我很确定它的内容/proc/sys/kernel/osrelease/proc/version发生变化,因为该发行版不会由 Microsoft 编译。

于 2016-09-21T22:39:38.963 回答
6

我刚刚为我的 .bashrc 想出了这个,用于将一些 WSL 项目添加到 $PATH。

适用于 1703 年。不确定是否为早期版本。

if [[ $(uname -r) =~ Microsoft$ ]]; then
    foo
fi
于 2017-05-05T00:54:21.027 回答
4

Without me doing anything special, these environment variables seem to be set already:

$ set | grep WSL
IS_WSL='Linux version 4.4.0-18362-Microsoft (Microsoft@Microsoft.com) (gcc version 5.4.0 (GCC) ) #1-Microsoft Mon Mar 18 12:02:00 PST 2019'
WSLENV=
WSL_DISTRO_NAME=Debian

So, something like the following snippet should also work in this case (example of what I used it for myself):

if [ ! -z "$IS_WSL" ]; then
    alias code='/mnt/c/Users/per/AppData/Local/Programs/Microsoft\ VS\ Code/Code.exe'
fi

(Note that technically, -z does not check if the variable is unset, merely that it is empty; in practice, this works well enough in this case. The ! at the beginning is there to negate the check.)

于 2019-09-07T18:04:08.317 回答
2

我需要测试macOS除了Windows Subsystem for Linux 2.

这是为我们工作的最简单的事情。

if [[ $OSTYPE == darwin* ]]; then
  # macOS
elif [[ "$(</proc/sys/kernel/osrelease)" == *microsoft* ]]; then
  # WSL2
else
  # Other *nix distro.
fi

注意:if顺序很重要。在 macOS 上,您在查看proc/version.
/proc/version: 没有这样的文件或目录


在最佳答案的评论中向@Niklas Holm 和@Marc Cornellà 致敬,让我瞄准正确的 WSL 检查。

于 2020-02-18T04:46:15.180 回答
2
if [[ `uname -a | grep -i linux | grep -i microsoft`  != "" ]]; then echo "microsoft wsl"; fi;

或多行语法:

if [[ `uname -a | grep -i linux | grep -i microsoft`  != "" ]]; then 
    echo "microsoft wsl" 
fi

注意:条件必须包含在反引号中,否则会产生错误,例如:

zsh: parse error: condition expected: uname

于 2021-04-24T14:03:00.373 回答
1

防故障测试:

grep -qi -- '-WSL' /proc/sys/kernel/osrelease || test -f /proc/sys/fs/binfmt_misc/WSLInterop

理由:

  1. 解析/proc/version是危险的。它可能包含误导性信息(想象一下由 microsoft 编译的 gcc)。最好只解析内核版本。
  2. WSL2:没有任何 WSL... 环境变量。(WINDOWS 10 20H2 build 19042.1165,UBUNTU 18.04.5 LTS,内核 5.10.16.3-microsoft-standard-WSL2)
  3. 如果内核版本的测试失败,则会进行第二次测试。

注意:有两个测试,从第一个测试中我删除了microsoft和 grep 仅在-WSL上。在这种最简单的形式中,它几乎是万无一失的。

binfmt_misc模板文件(用于在 linux 下运行 Windows 可执行文件)同时存在于 WSL 和 WSL2 上。

于 2021-08-26T12:21:40.153 回答
0

对于 WSL2,我们无法再通过内核版本进行检测,因为它在 Hyper-V 中运行实际的 Linux 内核。但是,它仍然可以explorer.exe在每个 Windows 安装中调用现有的。所以我们可以...

if [ -x "$(command -v explorer.exe)" ]; then
echo "We are running on WSL"
fi

这应该是一种更通用的方法来检测脚本是否在 WSL 上运行。

编辑:见上面的答案。我忘了计算像 Msys2 这样的类 Unix 环境。

于 2020-01-18T09:26:05.647 回答
0

If you in Bash and want to avoid fork:

is_wsl=0
read os </proc/sys/kernel/osrelease || :
if [[ "$os" == *Microsoft ]]; then
  is_wsl=1
fi
于 2019-05-15T13:35:08.703 回答
0

这是我放入 .bashrc 的内容

if [[ $(uname -v | sed -rE 's/^#[0-9]{3,}-(\S+).+/\1/') == "Microsoft" ]]; then
  # WSL-specific code
fi
  • uname -v 获取格式为的内核版本,#379-Microsoft Wed Mar 06 19:16:00 PST 2019然后 sed 表达式提取Microsoft字符串。
于 2019-04-02T20:24:40.303 回答
0

@Shital Shah 答案的更简洁的版本。

[ -n "$IS_WSL" ] || [ -n "$WSL_DISTRO_NAME" ] && echo 'wsl' || echo 'anything else'

于 2022-02-21T23:11:50.400 回答
0

由于 WSL1 和 WSL2 的区别在于第一个在容器中运行,而第二个在虚拟机中运行,我们可以使用“systemd-detect-virt --container”来区分这两种环境。

if [ -n "${WSL_DISTRO_NAME}" ]; then
  # In WSL but which one?
  virt_container="$(systemd-detect-virt --container)"
  case ${virt_container} in
    wsl)
      echo "This is WSL 1"
      ;;
    none)
      echo "This is WSL 2"
      ;;
    *)
      echo "Don't known ${virt_container}"
      ;;
  esac
fi
于 2021-07-28T00:49:19.483 回答
0

Windows 10 Pro Insider Preview Build 18917 中适用于 Linux 2 (WSL 2) 的 Windows 子系统

/proc/version 包含:

Linux 版本 4.19.43-microsoft-standard (oe-user@oe-host) (gcc 版本 7.3.0 (GCC)) #1 SMP...

于 2019-06-20T21:00:41.487 回答