当前位置:  开发笔记 > 编程语言 > 正文

如何检查是否在Cygwin,Mac或Linux中运行?

如何解决《如何检查是否在Cygwin,Mac或Linux中运行?》经验,为你挑选了6个好方法。

我有一个shell脚本,可以在Windows/Cygwin,Mac和Linux上使用.每个版本需要稍微不同的变量.

shell/bash脚本如何检测它是在Cygwin,Mac或Linux上运行?



1> Albert..:
这是我用来检测三种不同操作系统类型的bash脚本(GNU/Linux,Mac OS X,Windows NT)

请注意

在你的bash脚本中,使用#!/usr/bin/env bash而不是#!/bin/sh为了防止/bin/sh链接到不同平台上的不同默认shell 引起的问题,或者会出现意外操作符这样的错误,这就是我的计算机上发生的事情(Ubuntu 64位12.04).

Mac OS X 10.6.8(Snow Leopard)没有expr程序,除非你安装它,所以我只是使用uname.

设计

    使用uname来获取系统信息(-s参数).

    使用exprsubstr处理字符串.

    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

测试

Linux(Ubuntu 12.04 LTS,内核3.2.0)测试好了.

OS X(10.6.8 Snow Leopard)测试好了.

Windows(Windows 7 64位)测试正常.

我学到的是

    检查开盘价和收盘价.

    检查是否缺少括号和括号{}

参考

[1] uname - 维基百科

[2] shell脚本语法错误:意外的文件结束

[3] 从Bash脚本中检测操作系统

[4] BASH编程介绍如何操作


@DawidFerenczy我相信它需要双括号,如`if [[$(uname -s)== CYGWIN*]]; 然后`
@Albert:表达式`"$(expr substr $(uname -s)1 5)"`有点怪异.有更多漂亮的方法可以做到这一点,例如:`if [\`uname -s \`== CYGWIN*]; then`.读它:如果`uname -s`以*CYGWIN*开头那么......
为什么这只检查Linux的前5个字符?是否有现代Linux发行版的例子,其中`uname -s`会产生"Linux"以外的东西?

2> paxdiablo..:

通常,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和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}

请注意,我假设您实际上 CygWin(bash它的shell)中运行,因此路径应该已经正确设置.正如一位评论者所指出的那样,您可以运行bash程序,从而cmd自行传递脚本,这可能会导致路径未按需设置.

如果你正在这样做,这是你的责任,以确保正确的可执行文件(即,在Cygwin的)都被调用,可能是由事先修改路径或完全指定可执行文件的位置(例如,/c/cygwin/bin/uname).


有时少即是多了;)BTW,维基百科在http://en.wikipedia.org/wiki/Uname上有一个示例uname输出表
Git Bash不是Cygwin.它是MinGW,MS Windows的最小GNU,这就是行为不同的原因.

3> olibre..:

某些操作系统不支持使用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

以下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.请提供帮助以使其保持最新(编辑答案或发表评论).您还可以更新维基百科文章并发表评论以通知我您的贡献;-)

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


我在投票,就是这样.
赞成以上的Solaris和研究。

4> Jonathan Har..:

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

星号在某些情况下很重要 - 例如OSX在'darwin'之后附加OS版本号.'win'值实际上是'win32',我被告知 - 也许有'win64'?

也许我们可以在这里共同填写一份经过验证的值表:

Linux Ubuntu(包括WSL):linux-gnu

Cygwin 64位: cygwin

Msys/MINGW(适用于Windows的Git Bash): msys

(如果它与现有条目不同,请附加您的值)


从技术上讲,它不是一个环境变量,它是一个shell变量.这就是为什么你不会在`env |下看到它 grep OSTYPE`,但你会在`set |下看到它 grep OSTYPE`
对于那些感兴趣的人,Bash的`OSTYPE`变量[(conftypes.h)](http://git.savannah.gnu.org/cgit/bash.git/tree/conftypes.h)是在构建时使用精确副本配置的automake的`OS`变量[(Makefile.in)](http://git.savannah.gnu.org/cgit/bash.git/tree/Makefile.in?id=a0c0a00fc419b7bc08202a79134fcd5bc0427071#n145).有关所有可用类型,可以查阅automake的[lib/config.sub](http://git.savannah.gnu.org/cgit/automake.git/tree/lib/config.sub)文件.

5> Steve Jansen..:

为了建立在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

这避免了解析Windows名称的$OS变体,并解析uname类似MINGW,Cygwin等的变体.

背景:%COMSPEC%是一个Windows环境变量,指定命令处理器(也称为Windows shell)的完整路径.通常%SystemRoot%\system32\cmd.exe,此变量的值通常计算为C:\Windows\system32\cmd.exe.



6> 小智..:
# This script fragment emits Cygwin rulez under bash/cygwin
if [[ $(uname -s) == CYGWIN* ]];then
    echo Cygwin rulez
else 
    echo Unix is king
fi

如果uname -s命令的6个第一个字符是"CYGWIN",则假定为cygwin系统


是的,但使用双括号:`[[$(uname -s)== CYGWIN*]]`.另请注意,扩展正则表达式在我们的例子中更精确:`[[$(uname -s)=〜^ CYGWIN*]]`.
推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有