本文翻译自:How to check if running in Cygwin, Mac or Linux?
I have a shell script that is used both on Windows/Cygwin and Mac and Linux. 我有一个shell脚本,可以在Windows / Cygwin,Mac和Linux上使用。 It needs slightly different variables for each versions. 每个版本需要稍微不同的变量。
How can a shell/bash script detect whether it is running in Cygwin, on a Mac or in Linux? shell / bash脚本如何检测它是在Cygwin,Mac或Linux上运行?
#1楼
参考:https://stackoom.com/question/exHU/如何检查是否在Cygwin-Mac或Linux中运行
#2楼
# This script fragment emits Cygwin rulez under bash/cygwin
if [[ $(uname -s) == CYGWIN* ]];then
echo Cygwin rulez
else
echo Unix is king
fi
If the 6 first chars of uname -s command is "CYGWIN", a cygwin system is assumed 如果uname -s命令的6个第一个字符是“CYGWIN”,则假定为cygwin系统
#3楼
Here is the bash script I used to detect three different OS type (GNU/Linux, Mac OS X, Windows NT) 这是我用来检测三种不同操作系统类型的bash脚本(GNU / Linux,Mac OS X,Windows NT)
Pay attention 请注意
- In your bash script, use
#!/usr/bin/env bash
instead of#!/bin/sh
to prevent the problem caused by/bin/sh
linked to different default shell in different platforms, or there will be error like unexpected operator , that's what happened on my computer (Ubuntu 64 bits 12.04). 在你的bash脚本,使用#!/usr/bin/env bash
,而不是#!/bin/sh
,以防止因问题/bin/sh
像意外操作连接到不同的默认外壳在不同的平台上,否则会有错误,这就是我的电脑上发生的事情(Ubuntu 64 bit 12.04)。 - Mac OS X 10.6.8 (Snow Leopard) do not have
expr
program unless you install it, so I just useuname
. 除非你安装了Mac OS X 10.6.8(Snow Leopard)没有expr
程序,所以我只使用uname
。
Design 设计
- Use
uname
to get the system information (-s
parameter). 使用uname
获取系统信息(-s
参数)。 - Use
expr
andsubstr
to deal with the string. 使用expr
和substr
来处理字符串。 - Use
if
elif
fi
to do the matching job. 使用if
elif
fi
来完成匹配的工作。 - You can add more system support if you want, just follow the
uname -s
specification. 如果需要,可以添加更多系统支持,只需遵循uname -s
规范即可。
Implementation 履行
#!/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) tested OK. Linux(Ubuntu 12.04 LTS,内核3.2.0)测试好了。
- OS X (10.6.8 Snow Leopard) tested OK. OS X(10.6.8 Snow Leopard)测试好了。
- Windows (Windows 7 64 bit) tested OK. Windows(Windows 7 64位)测试正常。
What I learned 我学到的是
- Check for both opening and closing quotes. 检查开盘价和收盘价。
- Check for missing parentheses and braces {} 检查是否缺少括号和括号{}
References 参考
- [1] uname - wikipedia [1] uname - 维基百科
- [2] shell script syntax error: unexpected end of file [2] shell脚本语法错误:意外的文件结束
- [3] Detect the OS from a Bash script [3] 从Bash脚本中检测操作系统
- [4] BASH Programming Introduction HOW-TO [4] BASH编程介绍如何操作
#4楼
To build upon Albert's answer, I like to use $COMSPEC
for detecting Windows: 为了建立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
This avoids parsing variants of Windows names for $OS
, and parsing variants of uname
like MINGW, Cygwin, etc. 这样可以避免为$OS
解析Windows名称的变体,并解析像MINGW,Cygwin等的uname
变体。
Background: %COMSPEC%
is a Windows environmental variable specifying the full path to the command processor (aka the Windows shell). 背景: %COMSPEC%
是Windows环境变量,指定命令处理器(也称为Windows shell)的完整路径。 The value of this variable is typically %SystemRoot%\\system32\\cmd.exe
, which typically evaluates to C:\\Windows\\system32\\cmd.exe
. 此变量的值通常为%SystemRoot%\\system32\\cmd.exe
,通常计算结果为C:\\Windows\\system32\\cmd.exe
。
#5楼
Use only this from command line works very fine, thanks to Justin: 感谢Justin,只使用命令行中的这个工作非常好
#!/bin/bash
################################################## #########
# Bash script to find which OS
################################################## #########
OS=`uname`
echo "$OS"
#6楼
Use uname -s
( --kernel-name
) because uname -o
( --operating-system
) is not supported on some Operating Systems as Mac OS , Solaris . 使用uname -s
( - --kernel-name
),因为某些操作系统不支持uname -o
( - --operating-system
)作为Mac OS , Solaris 。 You may also use just uname
without argument as the default argument is -s
( --kernel-name
). 您也可以只使用uname
而不使用参数,因为默认参数是-s
( - --kernel-name
)。
The below snippet does not require bash (ie does not require #!/bin/bash
) 下面的代码片段不需要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
The below Makefile
is inspired from Git project ( config.mak.uname
) . 下面的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
...
See also this complete answer about uname -s
and Makefile
. 另请参阅有关uname -s
和Makefile
完整答案 。
The correspondence table in the bottom of this answer is from Wikipedia article about uname
. 这个答案底部的对应表来自维基百科关于uname
文章 。 Please contribute to keep it up-to-date (edit the answer or post a comment). 请提供帮助以使其保持最新(编辑答案或发表评论)。 You may also update the Wikipedia article and post a comment to notice me about your contribution ;-) 您还可以更新维基百科文章并发表评论以通知我您的贡献;-)
Operating System
uname -s
Operating System
uname -s
Mac OS X
Darwin
Mac OS X
Darwin
Cygwin 32-bit (Win-XP)
CYGWIN_NT-5.1
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 32-bit)
CYGWIN_NT-6.1
Cygwin 32-bit (Win-7 64-bit)
CYGWIN_NT-6.1-WOW64
Cygwin 32-bit (Win-7 64-bit)
CYGWIN_NT-6.1-WOW64
Cygwin 64-bit (Win-7 64-bit)
CYGWIN_NT-6.1
Cygwin 64-bit (Win-7 64-bit)
CYGWIN_NT-6.1
MinGW (Windows 7 32-bit)
MINGW32_NT-6.1
MinGW (Windows 7 32-bit)
MINGW32_NT-6.1
MinGW (Windows 10 64-bit)
MINGW64_NT-10.0
MinGW (Windows 10 64-bit)
MINGW64_NT-10.0
Interix (Services for UNIX)
Interix
MSYS
MSYS_NT-6.1
Windows Subsystem for Linux
Linux
Interix (Services for UNIX)
Interix
MSYS
MSYS_NT-6.1
Windows Subsystem for Linux
Linux
Windows Subsystem for Linux
Android
Linux
Android
Linux
coreutils
Linux
coreutils
Linux
CentOS
Linux
CentOS
Linux
Fedora
Linux
Fedora
Linux
Gentoo
Linux
Gentoo
Linux
Red Hat Linux
Linux
Red Hat Linux
Linux
Linux Mint
Linux
Linux Mint
Linux
openSUSE
Linux
openSUSE
Linux
Ubuntu
Linux
Ubuntu
Linux
Unity Linux
Linux
Unity Linux
Linux
Manjaro Linux
Linux
Manjaro Linux
Linux
OpenWRT r40420
Linux
OpenWRT r40420
Linux
Debian (Linux)
Linux
Debian (Linux)
Linux
Debian (GNU Hurd)
GNU
Debian (GNU Hurd)
GNU
Debian (kFreeBSD)
GNU/kFreeBSD
Debian (kFreeBSD)
GNU/kFreeBSD
FreeBSD
FreeBSD
FreeBSD
FreeBSD
NetBSD
NetBSD
NetBSD
NetBSD
DragonFlyBSD
DragonFly
DragonFlyBSD
DragonFly
Haiku
Haiku
Haiku
Haiku
NonStop
NONSTOP_KERNEL
NonStop
NONSTOP_KERNEL
QNX
QNX
QNX
QNX
ReliantUNIX
ReliantUNIX-Y
ReliantUNIX
ReliantUNIX-Y
SINIX
SINIX-Y
SINIX
SINIX-Y
Tru64
OSF1
Tru64
OSF1
Ultrix
ULTRIX
Ultrix
ULTRIX
IRIX 32 bits
IRIX
IRIX 32 bits
IRIX
IRIX 64 bits
IRIX64
IRIX 64 bits
IRIX64
MINIX
Minix
MINIX
Minix
Solaris
SunOS
Solaris
SunOS
UWIN (64-bit Windows 7)
UWIN-W7
UWIN (64-bit Windows 7)
UWIN-W7
SYS$UNIX:SH on OpenVMS
IS/WB
SYS$UNIX:SH on OpenVMS
IS/WB
SYS$UNIX:SH on OpenVMS
z/OS USS
OS/390
z/OS USS
OS/390
Cray
sn5176
Cray
sn5176
(SCO) OpenServer
SCO_SV
(SCO) OpenServer
SCO_SV
(SCO) System V
SCO_SV
(SCO) System V
SCO_SV
(SCO) UnixWare
UnixWare
(SCO) UnixWare
UnixWare
IBM AIX
AIX
IBM AIX
AIX
IBM i with QSH
OS400
IBM i with QSH
OS400
HP-UX
HP-UX
HP-UX
HP-UX