我有一个shell脚本,在Windows/Cygwin和Mac和Linux上都使用。每个版本都需要稍微不同的变量。
shell/bash脚本如何检测它是在Cygwin、Mac还是Linux上运行?
我有一个shell脚本,在Windows/Cygwin和Mac和Linux上都使用。每个版本都需要稍微不同的变量。
shell/bash脚本如何检测它是在Cygwin、Mac还是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)。
其他回答
当提出这个问题时,Linux的Windows子系统还不存在。它在我的测试中给出了以下结果:
uname -s -> Linux
uname -o -> GNU/Linux
uname -r -> 4.4.0-17763-Microsoft
这意味着您需要使用uname -r来将其与本地Linux区分开来。
我想无名的答案是无敌的,主要是在清洁方面。
虽然执行它需要很长时间,但我发现测试特定文件的存在也会给我更好和更快的结果,因为我没有调用可执行文件:
So,
[-f /usr/bin/cygwin1.dll] && echo是的,Cygwin正在运行
只是使用一个快速的Bash文件存在检查。因为我现在使用的是Windows,所以我无法告诉你任何linux和Mac OS X的具体文件,但我非常确定它们确实存在。: -)
Bash设置shell变量OSTYPE。来自man bash:
自动设置为描述操作系统的字符串 哪个bash正在执行。
这比uname有一个小小的优势,它不需要启动一个新进程,因此执行起来更快。
然而,我无法找到一个权威的期望值列表。对我来说,Ubuntu 14.04设置为“linux-gnu”。我在网上搜到了一些其他的价值。因此:
case "$OSTYPE" in
linux*) echo "Linux / WSL" ;;
darwin*) echo "Mac OS" ;;
win*) echo "Windows" ;;
msys*) echo "MSYS / MinGW / Git Bash" ;;
cygwin*) echo "Cygwin" ;;
bsd*) echo "BSD" ;;
solaris*) echo "Solaris" ;;
*) echo "unknown: $OSTYPE" ;;
esac
星号在某些情况下很重要——例如,OSX在“darwin”之后附加了一个操作系统版本号。“win”值实际上是“win32”,我被告知-也许有一个“win64”?
也许我们可以一起工作,在这里填充一个验证值的表:
Linux Ubuntu(包括。WSL): Linux -gnu Cygwin 64位:Cygwin Msys/MINGW (Git Bash for Windows): Msys
(如果与现有条目不同,请附加您的值)
# This script fragment emits Cygwin rulez under bash/cygwin
if [[ $(uname -s) == CYGWIN* ]];then
echo Cygwin rulez
else
echo Unix is king
fi
如果uname -s命令的前6个字符为“CYGWIN”,则假设系统为CYGWIN
通常,带有各种选项的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)。