我有一个shell脚本,在Windows/Cygwin和Mac和Linux上都使用。每个版本都需要稍微不同的变量。

shell/bash脚本如何检测它是在Cygwin、Mac还是Linux上运行?


当前回答

http://en.wikipedia.org/wiki/Uname

所有你需要的信息。谷歌是你的朋友。

使用uname -s命令查询系统名称。

麦克:达尔文 Cygwin: CYGWIN_… Linux:多种多样,Linux为大多数

其他回答

我想无名的答案是无敌的,主要是在清洁方面。

虽然执行它需要很长时间,但我发现测试特定文件的存在也会给我更好和更快的结果,因为我没有调用可执行文件:

So,

[-f /usr/bin/cygwin1.dll] && echo是的,Cygwin正在运行

只是使用一个快速的Bash文件存在检查。因为我现在使用的是Windows,所以我无法告诉你任何linux和Mac OS X的具体文件,但我非常确定它们确实存在。: -)

当提出这个问题时,Linux的Windows子系统还不存在。它在我的测试中给出了以下结果:

uname -s -> Linux
uname -o -> GNU/Linux
uname -r -> 4.4.0-17763-Microsoft

这意味着您需要使用uname -r来将其与本地Linux区分开来。

http://en.wikipedia.org/wiki/Uname

所有你需要的信息。谷歌是你的朋友。

使用uname -s命令查询系统名称。

麦克:达尔文 Cygwin: CYGWIN_… Linux:多种多样,Linux为大多数

通常,带有各种选项的uname会告诉你正在运行的环境:

pax> uname -a
CYGWIN_NT-5.1 IBM-L3F3936 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwin

pax> uname -s
CYGWIN_NT-5.1

而且,根据非常有用的肖特(在评论中),uname -s为OSX提供Darwin,为Linux提供Linux,而我的Cygwin提供CYGWIN_NT-5.1。但是你可能要尝试各种不同的版本。

因此,执行此类检查的bash代码将如下所示:

unameOut="$(uname -s)"
case "${unameOut}" in
    Linux*)     machine=Linux;;
    Darwin*)    machine=Mac;;
    CYGWIN*)    machine=Cygwin;;
    MINGW*)     machine=MinGw;;
    *)          machine="UNKNOWN:${unameOut}"
esac
echo ${machine}

注意,我在这里假设您实际上是在CygWin(它的bash shell)中运行,因此路径应该已经正确设置。正如一位评论者指出的那样,你可以从cmd本身运行bash程序,传递脚本,这可能会导致路径没有按需要设置。

如果你这样做,你有责任确保正确的可执行文件(例如CygWin的)被调用,可能是通过事先修改路径或完全指定可执行文件的位置(例如,/c/ CygWin /bin/uname)。

好的,这是我的方法。

osis()
{
    local n=0
    if [[ "$1" = "-n" ]]; then n=1;shift; fi

    # echo $OS|grep $1 -i >/dev/null
    uname -s |grep -i "$1" >/dev/null

    return $(( $n ^ $? ))
}

e.g.

osis Darwin &&
{
    log_debug Detect mac osx
}
osis Linux &&
{
    log_debug Detect linux
}
osis -n Cygwin &&
{
    log_debug Not Cygwin
}

我在我的dotfiles中使用这个