bas*_*ibe 297 bash shell cygwin cross-platform
我有一个shell脚本,可以在Windows/Cygwin,Mac和Linux上使用.每个版本需要稍微不同的变量.
shell/bash脚本如何检测它是在Cygwin,Mac或Linux上运行?
Alb*_*ert 304
#!/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
Run Code Online (Sandbox Code Playgroud)
pax*_*blo 275
通常,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
Run Code Online (Sandbox Code Playgroud)
并且,根据非常有用的schot(在评论中),uname -s给出Darwin了OSX和LinuxLinux,而我的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}
Run Code Online (Sandbox Code Playgroud)
请注意,我假设您实际上在 CygWin(bash它的shell)中运行,因此路径应该已经正确设置.正如一位评论者所指出的那样,您可以运行bash程序,从而cmd自行传递脚本,这可能会导致路径未按需设置.
如果你正在这样做,这是你的责任,以确保正确的可执行文件(即,在Cygwin的)都被调用,可能是由事先修改路径或完全指定可执行文件的位置(例如,/c/cygwin/bin/uname).
oli*_*bre 110
某些操作系统不支持使用uname -s(--kernel-name)因为uname -o(--operating-system),如Mac OS,Solaris.您也可以使用uname不带参数,因为默认参数是-s(--kernel-name).
以下代码段不需要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
Run Code Online (Sandbox Code Playgroud)
以下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
...
Run Code Online (Sandbox Code Playgroud)
这个答案底部的对应表来自维基百科的文章uname.请提供帮助以使其保持最新(编辑答案或发表评论).您还可以更新维基百科文章并发表评论以通知我您的贡献;-)
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
MSYS2 MSYS_NT-10.0-17763
Windows Subsystem for Linux Linux
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
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
Jon*_*ley 60
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
Run Code Online (Sandbox Code Playgroud)
星号在某些情况下很重要 - 例如OSX在'darwin'之后附加OS版本号.'win'值实际上是'win32',我被告知 - 也许有'win64'?
也许我们可以在这里共同填写一份经过验证的值表:
linux-gnucygwinmsys(如果它与现有条目不同,请附加您的值)
为了建立在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
Run Code Online (Sandbox Code Playgroud)
这避免了解析Windows名称的$OS变体,并解析uname类似MINGW,Cygwin等的变体.
背景:%COMSPEC%是一个Windows环境变量,指定命令处理器(也称为Windows shell)的完整路径.通常%SystemRoot%\system32\cmd.exe,此变量的值通常计算为C:\Windows\system32\cmd.exe.
小智 8
# This script fragment emits Cygwin rulez under bash/cygwin
if [[ $(uname -s) == CYGWIN* ]];then
echo Cygwin rulez
else
echo Unix is king
fi
Run Code Online (Sandbox Code Playgroud)
如果uname -s命令的6个第一个字符是"CYGWIN",则假定为cygwin系统
http://en.wikipedia.org/wiki/Uname
您需要的所有信息。谷歌是你的朋友。
使用uname -s查询系统名称。
DarwinCYGWIN_...LINUX大多数