如何检查在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 -sDarwin提供了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脚本,

请注意

  • 在你的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,Kernel 3.2.0)测试OK。
  • OS X(10.6.8雪豹)测试OK。
  • Windows(Windows 7 64位)测试确定。
  • 我学到的是

  • 检查开盘和收盘报价。
  • 检查缺少的括号和大括号{}
  • 参考

  • [1] uname - 维基百科
  • [2] shell脚本语法错误:文件意外结束
  • [3]从Bash脚本中检测操作系统
  • [4] BASH编程介绍HOWTOO

  • 使用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 -sMakefile完美答案。

    这个答案底部的对应表来自维基百科关于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

    链接地址: http://www.djcxy.com/p/17507.html

    上一篇: How to check if running in Cygwin, Mac or Linux?

    下一篇: Automatic exit from bash shell script on error