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和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}
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-gnu
cygwin
msys
(如果它与现有条目不同,请附加您的值)
为了建立在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
查询系统名称。
Darwin
CYGWIN_...
LINUX
大多数 归档时间: |
|
查看次数: |
125876 次 |
最近记录: |