如何检查在Cygwin,Mac或Linux上运行?
我有一个在Windows / Cygwin和Mac和Linux上都使用的shell脚本。 每个版本都需要稍微不同的变量。
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
而且,根据非常有用的schot
(在评论中), uname -s
为Darwin
提供了OSX和Linux
for 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
)。
这里是我用来检测三种不同操作系统类型(GNU / Linux,Mac OS X,Windows NT)的bash脚本,
请注意
#!/usr/bin/env bash
而不是#!/bin/sh
来防止由/bin/sh
引起的问题链接到不同平台的不同默认shell,否则会出现意外运算符,这就是我的电脑上发生的事情(Ubuntu 64位12.04)。 expr
程序,所以我只使用uname
。 设计
uname
获取系统信息( -s
参数)。 expr
和substr
来处理字符串。 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
测试
我学到的是
参考
使用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
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