How to check if a program is run in Bash on Ubuntu on Windows and not just plain Ubuntu?

有些话、适合烂在心里 提交于 2019-11-27 19:09:35

问题


Pretty straightforward, the usual places to figure out the OS you're on seem to be identical to plain Ubuntu on Ubuntu for Windows. For example uname -a is identical to a native GNU/Linux install and /etc/os-version is identical to a Ubuntu Trusty Tahr install.

The only thing I can think of is to check if /mnt/c/Windows exists, but I'm not sure if that's a foolproof idea.


回答1:


The following works in bash on Windows 10, macOS, and Linux:

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

You need to check for both "Microsoft" and "WSL" per this comment by Ben Hillis, WSL Developer:

For the time being this is probably the best way to do it. I can't promise that we'll never change the content of these ProcFs files, but I think it's unlikely we'll change it to something that doesn't contain "Microsoft" or "WSL".

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



回答2:


I've been looking for ways to detect that as well. So far I've found 2.

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

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

If you just use the Ubuntu distribution installed by default there should be no problems with using them, as they said that it would be unlikely for them to set either to something that doesn't contain "Microsoft" or "WSL".

However, if you were to install a different Linux distribution, I'm pretty sure that the contents of /proc/sys/kernel/osrelease and /proc/version will change, since the distro wouldn't have been compiled by Microsoft.




回答3:


I just came up with this for my .bashrc for adding some WSL items to $PATH.

Works in 1703. Not sure if earlier versions.

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



回答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.)




回答5:


Here's what I put in my .bashrc

if [[ $(uname -v | sed -rE 's/^#[0-9]{3,}-(\S+).+/\1/') == "Microsoft" ]]; then
  # WSL-specific code
fi
  • uname -v gets the kernel version in the format of #379-Microsoft Wed Mar 06 19:16:00 PST 2019 and the sed expression pulls out the Microsoft string.



回答6:


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



回答7:


Windows Subsystem for Linux 2 (WSL 2) in Windows 10 Pro Insider Preview Build 18917

/proc/version contains:

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



来源:https://stackoverflow.com/questions/38086185/how-to-check-if-a-program-is-run-in-bash-on-ubuntu-on-windows-and-not-just-plain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!