如何检查在Cygwin,Mac或Linux上运行?
我有一个在Windows / Cygwin和Mac和Linux上使用的shell脚本。 每个版本都需要稍微不同的variables。
shell / bash脚本如何检测它是在Cygwin中,在Mac上还是在Linux中运行?
通常,不同的选项会告诉你在什么环境中运行:
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
而且,根据非常有用的schot
(在评论中), uname -s
给出了Darwin
的OSX和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}
这里是我用来检测三种不同的操作系统types(GNU / Linux,Mac OS X,Windows NT)的bash脚本,
请注意
- 在您的bash脚本中,使用
#!/usr/bin/env bash
而不是#!/bin/sh
来防止由/bin/sh
引起的问题链接到不同平台的不同默认shell,否则会出现意外操作 ,这就是我的电脑上发生的事情(Ubuntu 64位12.04)。 - Mac OS X 10.6.8(雪豹)没有
expr
程序,除非你安装它,所以我只使用uname
。
devise
- 使用
uname
获取系统信息(-s
参数)。 - 使用
expr
和substr
来处理string。 -
if
elif
fi
做匹配的工作,使用。 - 你可以添加更多的系统支持,只要按照
uname -s
规范。
履行
#!/usr/bin/env bash if [ "$(uname)" == "Darwin" ]; then # Do something under Mac OS X platform elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then # Do something under GNU/Linux platform elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then # Do something under 32 bits Windows NT platform elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then # Do something under 64 bits Windows NT platform fi
testing
- Linux(Ubuntu 12.04 LTS,Kernel 3.2.0)testingOK。
- OS X(10.6.8雪豹)testing确定。
- Windows(Windows 7 64位)testing确定。
我学到的是
- 检查开盘和收盘报价。
- 检查缺less的圆括号和大括号{}
参考
- [1] uname – 维基百科
- shell脚本语法错误:意外的文件结束
- [3] 从Bash脚本中检测操作系统
- [4] BASH编程介绍如何
使用uname -s
是因为uname -o
在某些操作系统上不受支持,如Mac OS , Solaris …
下面的代码片段不需要bash (即不需要#!/bin/bash
)
#!/bin/sh case "$(uname -s)" in Darwin) echo 'Mac OS X' ;; Linux) echo 'Linux' ;; CYGWIN*|MINGW32*|MSYS*) echo 'MS Windows' ;; # Add here more strings to compare # See correspondence table at the bottom of this answer *) echo 'other OS' ;; esac
下面的Makefile
受Git项目( config.mak.uname
)的启发。
ifdef MSVC # Avoid the MingW/Cygwin sections uname_S := Windows else # If uname not available => 'not' uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') endif # Avoid nesting "if .. else if .. else .. endif endif" # because maintenance of matching if/else/endif is a pain ifeq ($(uname_S),Windows) CC := cl endif ifeq ($(uname_S),OSF1) CFLAGS += -D_OSF_SOURCE endif ifeq ($(uname_S),Linux) CFLAGS += -DNDEBUG endif ifeq ($(uname_S),GNU/kFreeBSD) CFLAGS += -D_BSD_ALLOC endif ifeq ($(uname_S),UnixWare) CFLAGS += -Wextra endif ...
另请参阅关于uname -s
和Makefile
完美答案 。
这个答案的底部的对应表是从维基百科有关uname
文章 。 请捐助,以保持最新(编辑答案或发表评论)。 您也可以更新维基百科文章并发表评论,以通知我有关您的贡献;-)
参见Git LSF的安装脚本所做的更复杂的操作系统检测。
Operating System
uname -s
Mac OS X
Darwin
Cygwin 32-bit (Win-XP)
CYGWIN_NT-5.1
Cygwin 32-bit (Win-7 32-bit)
CYGWIN_NT-6.1
Cygwin 32-bit (Win-7 64-bit)
CYGWIN_NT-6.1-WOW64
Cygwin 64-bit (Win-7 64-bit)
CYGWIN_NT-6.1
MinGW (Windows 7 32-bit)
MINGW32_NT-6.1
MinGW (Windows 10 64-bit)
MINGW64_NT-10.0
Interix (Services for UNIX)
Interix
MSYS
MSYS_NT-6.1
Android
Linux
coreutils
Linux
CentOS
Linux
Fedora
Linux
Gentoo
Linux
Red Hat Linux
Linux
Linux Mint
Linux
openSUSE
Linux
Ubuntu
Linux
Unity Linux
Linux
Manjaro Linux
Linux
OpenWRT r40420
Linux
Debian (Linux)
Linux
Debian (GNU Hurd)
GNU
Debian (kFreeBSD)
GNU/kFreeBSD
FreeBSD
FreeBSD
NetBSD
NetBSD
DragonFlyBSD
DragonFly
Haiku
Haiku
Haiku
Haiku
NonStop
NONSTOP_KERNEL
QNX
QNX
ReliantUNIX
ReliantUNIX-Y
SINIX
SINIX-Y
Tru64
OSF1
Ultrix
ULTRIX
IRIX 32 bits
IRIX
IRIX 64 bits
IRIX64
MINIX
Minix
Solaris
SunOS
UWIN (64-bit Windows 7)
UWIN-W7
SYS$UNIX:SH on OpenVMS
IS/WB
SYS$UNIX:SH on OpenVMS
z/OS USS
OS/390
Cray
sn5176
(SCO) OpenServer
SCO_SV
(SCO) System V
SCO_SV
(SCO) UnixWare
UnixWare
IBM AIX
AIX
IBM i with QSH
OS400
HP-UX
HP-UX
Bash设置shellvariablesOSTYPE。 从man bash
:
自动设置为描述执行bash的操作系统的string。
这比uname
有一个小小的优势,因为它不需要启动一个新的进程,所以执行起来会更快。
但是,我无法find期望值的权威列表。 对于我在Ubuntu 14.04上它被设置为“linux-gnu”。 我已经刮了networking的一些其他的价值观。 因此:
case "$OSTYPE" in linux*) echo "LINUX" ;; darwin*) echo "OSX" ;; win*) echo "Windows" ;; cygwin*) echo "Cygwin" ;; bsd*) echo "BSD" ;; solaris*) echo "SOLARIS" ;; *) echo "unknown: $OSTYPE" ;; esac
星号在某些情况下非常重要,例如OSX在“达尔文”之后追加操作系统版本号。 “赢”的价值实际上是“win32”,我被告知 – 也许有一个“win64”?
也许我们可以一起工作,在这里填充一个validation值表:
- Linux Ubuntu(包括WSL ):
linux-gnu
- Cygwin 64位:
cygwin
- Msys /
msys
(Windows版Git Bash):msys
(如果与现有条目不同,请附上您的价值)
# This script fragment emits Cygwin rulez under bash/cygwin if [ "$(expr substr $(uname -s) 1 6)" == "CYGWIN" ];then echo Cygwin rulez else echo Unix is king fi
如果uname -s命令的前6个字符是“CYGWIN”,则假定为cygwin系统
基于Albert的回答,我喜欢使用$COMSPEC
来检测Windows:
#!/bin/bash if [ "$(uname)" == "Darwin" ] then echo Do something under Mac OS X platform elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ] then echo Do something under Linux platform elif [ -n "$COMSPEC" -a -x "$COMSPEC" ] then echo $0: this script does not support Windows \:\( fi
这样可以避免为$OS
parsingWindows名称的变体,parsing像MINGW,Cygwin等uname
变体。
背景: %COMSPEC%
是一个Windows环境variables,指定了命令处理器(即Windowsshell)的完整path。 此variables的值通常是%SystemRoot%\system32\cmd.exe
,通常评估为C:\Windows\system32\cmd.exe
。
http://en.wikipedia.org/wiki/Uname
所有你需要的信息。 Google是你的朋友。
使用uname -s
来查询系统名称。
- 麦克:
Darwin
- Cygwin:
CYGWIN_...
- Linux:大部分是
LINUX
好的,这是我的方式。
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 ^ $? )) }
例如
osis Darwin && { log_debug Detect mac osx } osis Linux && { log_debug Detect linux } osis -n Cygwin && { log_debug Not Cygwin }
我在我的dotfiles中使用这个
在命令行中只使用这个工作非常好,谢谢Justin:
#!/bin/bash ################################################## ######### # Bash script to find which OS ################################################## ######### OS=`uname` echo "$OS"
资源
我猜uname答案是无与伦比的,主要是在清洁方面。
虽然执行时间很荒谬,但是我发现testing特定文件的存在也给了我更好更快的结果,因为我没有调用可执行文件:
所以,
[ -f /usr/bin/cygwin1.dll ] && echo Yep, Cygwin running
只是使用一个快速的Bash文件存在检查。 因为我现在在Windows上,所以我不能告诉你任何Linuxes和Mac OS X的特定文件,但是我确信它们确实存在。 🙂