如何检查程序是否在Windows上的Ubuntu上运行Bash而不仅仅是普通的Ubuntu?

时间:2016-06-28 20:58:09

标签: linux windows bash ubuntu windows-subsystem-for-linux

非常简单,通常用于确定您所使用的操作系统的地方似乎与Ubuntu for Windows上的普通Ubuntu相同。例如,uname -a与本机GNU / Linux安装相同,/etc/os-version与Ubuntu Trusty Tahr安装相同。

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

12 个答案:

答案 0 :(得分:29)

以下适用于Windows 10,macOS和Linux上的bash:

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

您需要检查" Microsoft"和" WSL"每个this comment作者:Ben Hillis,WSL开发人员:

  

暂时这可能是最好的方法。我不能   承诺我们永远不会改变这些ProcF文件的内容,但是   我认为我们不太可能将其改为不合适的东西   包含"微软"或者" WSL"。

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

答案 1 :(得分:6)

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

  • /proc/sys/kernel/osrelease是" 3.4.0-Microsoft"

  • /proc/version是" Linux版本3.4.0-Microsoft (Microsoft@Microsoft.com)(gcc版本4.7(GCC))#1 SMP PREEMPT 星期三12月31日14:42:53太平洋标准时间2014"

如果你只是使用默认安装的Ubuntu发行版,那么使用它们应该没有问题,如they said that it would be unlikely for them to set either to something that doesn't contain "Microsoft" or "WSL"

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

答案 2 :(得分:5)

通过@ per-lundberg更新答案:

if [[ ! -z "$IS_WSL" && ! -z "$WSL_DISTRO_NAME" ]]; then
    echo "You are not in wsl!"
else
    echo "You are in wsl!"
fi

注意:IS_WSL存在于较早版本中,而WSL_DISTRO_NAME存在于当前版本中。

答案 3 :(得分:2)

我刚刚为我的.bashrc提出了这个问题,将一些WSL项目添加到$ PATH。

在1703中工作。不确定是否早期版本。

if [[ $(uname -r) =~ Microsoft$ ]]; then
    foo
fi

答案 4 :(得分:1)

没有做任何特别的事情,这些环境变量似乎已经设置好了:

$ 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

因此,在这种情况下(例如我自己使用的示例),类似以下代码段的内容也应该起作用:

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

(请注意,从技术上讲,-z does not check if the variable is unset仅仅是空的;实际上,在这种情况下,它已经足够好了。开头的!可以使检查无效。)

答案 5 :(得分:1)

除了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:没有这样的文件或目录


答案 6 :(得分: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字符串。

答案 7 :(得分:0)

如果您在Bash中并且想避免使用fork

is_wsl=0
read os </proc/sys/kernel/osrelease || :
if [[ "$os" == *Microsoft ]]; then
  is_wsl=1
fi

答案 8 :(得分:0)

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

/ proc / version包含:

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

答案 9 :(得分:0)

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

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

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

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

答案 10 :(得分:0)

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

答案 11 :(得分: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