代码之家  ›  专栏  ›  技术社区  ›  bastibe

如何检查是否在Cygwin、Mac或Linux下运行?

  •  263
  • bastibe  · 技术社区  · 14 年前

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

    shell/bash脚本如何检测它是在Cygwin、Mac还是Linux中运行?

    10 回复  |  直到 14 年前
        1
  •  370
  •   paxdiablo    7 年前

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

    在内部 赛文(女) 所以应该已经正确设置了路径。正如一位评论者指出的,您可以运行 程序,传递脚本,从 cmd 这可能会导致路径未按需要设置。

    /c/cygwin/bin/uname ).

        2
  •  347
  •   Community Dan Abramov    7 年前

    注意

    • #!/usr/bin/env bash 而不是 #!/bin/sh 以防止 /bin/sh 链接到不同平台的不同默认shell,否则会出现如下错误 意外运算符 ,这就是我的电脑上发生的事情(Ubuntu 64位12.04)。
    • expr 程序,除非你安装它,所以我只是使用 uname

    设计

    1. 使用 联塞特派团 获取系统信息( -s 参数)。
    2. 使用 substr 处理这根弦。
    3. 使用 if elif fi
    4. 如果需要,可以添加更多系统支持,只需按照 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(Ubuntu12.04 LTS,内核3.2.0)测试正常。
    • OSX(10.6.8雪豹)测试正常。
    • Windows(Windows 7 64位)测试正常。

    我学到了什么

    1. 检查开头和结尾的引号。

        3
  •  145
  •   Bruno Haible    4 年前

    使用 uname -s --kernel-name uname -o --operating-system Mac操作系统 Solaris系统 . 你也可以用just uname 没有任何争论 因为默认参数是 -s ( --内核名称 ).

    下面的代码段不需要 #!/bin/bash )

    #!/bin/sh
    
    case "$(uname -s)" in
    
       Darwin)
         echo 'Mac OS X'
         ;;
    
       Linux)
         echo 'Linux'
         ;;
    
       CYGWIN*|MINGW32*|MSYS*|MINGW*)
         echo 'MS Windows'
         ;;
    
       # Add here more strings to compare
       # See correspondence table at the bottom of this answer
    
       *)
         echo 'Other OS' 
         ;;
    esac
    

    Makefile 灵感来自 Git project ( 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
    ...
    

    另请参见 this complete answer about uname -s and Makefile .

    这个答案下面的对应表来自 Wikipedia article about 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) 青温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
    Unity Linux Linux操作系统
    Manjaro Linux
    OpenWRT r40420 Linux操作系统
    Debian (Linux) Linux操作系统
    Debian (GNU Hurd) GNU
    Debian (kFreeBSD) GNU/kFreeBSD
    FreeBSD FreeBSD
    NetBSD NetBSD
    OpenBSD OpenBSD
    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) UnixWare UnixWare
    IBM AIX AIX
    IBM i with QSH OS400
    HP-UX HP-UX

        4
  •  72
  •   Jonathan Hartley    6 年前

    Bash设置shell变量OSTYPE。从 man bash

    自动设置为描述上的操作系统的字符串

    相比之下,这有一点优势 uname 因为它不需要启动新的进程,所以执行起来会更快。

    但是,我找不到预期值的权威列表。对我来说,在ubuntu14.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(Git Bash for Windows): msys

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

        5
  •  12
  •   doekman    6 年前
    # This script fragment emits Cygwin rulez under bash/cygwin
    if [[ $(uname -s) == CYGWIN* ]];then
        echo Cygwin rulez
    else 
        echo Unix is king
    fi
    

        6
  •  9
  •   Steve Jansen    11 年前

    $COMSPEC 用于检测窗口:

    #!/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
    

    $OS uname 像明哥、赛文等。

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

        7
  •  4
  •   fejese    9 年前

    http://en.wikipedia.org/wiki/Uname

    所有你需要的信息。谷歌是你的朋友。

    uname -s 查询系统名称。

    • 雨衣: Darwin
    • 赛文: CYGWIN_...
    • Linux:多种多样, LINUX
        8
  •  3
  •   A Fog    5 年前

    提出此问题时,Linux的Windows子系统不存在。它在我的测试中给出了以下结果:

    uname -s -> Linux
    uname -o -> GNU/Linux
    uname -r -> 4.4.0-17763-Microsoft
    

    这意味着您需要uname-r来区分它与本机Linux。

        9
  •  2
  •   wener    9 年前

    好的,这是我的路。

    osis()
    {
        local n=0
        if [[ "$1" = "-n" ]]; then n=1;shift; fi
    
        # echo $OS|grep $1 -i >/dev/null
        uname -s |grep -i "$1" >/dev/null
    
        return $(( $n ^ $? ))
    }
    

    例如

    osis Darwin &&
    {
        log_debug Detect mac osx
    }
    osis Linux &&
    {
        log_debug Detect linux
    }
    osis -n Cygwin &&
    {
        log_debug Not Cygwin
    }
    

    我在我的生活中用这个 dotfiles

        10
  •  1
  •   Charles Roberto Canato    9 年前

    尽管执行起来花费了很长时间,但我发现测试特定文件的存在性也会给我带来更好更快的结果,因为我没有调用可执行文件:

    [ -f /usr/bin/cygwin1.dll ] && echo Yep, Cygwin running

    只是使用一个快速的Bash文件状态检查。由于我现在使用的是Windows,我无法从头脑中告诉您Linuxes和Mac OS X的任何特定文件,但我非常确定它们确实存在。:-)

        11
  •  -4
  •   lizardhr    10 年前

    从命令行只用这个就行了, 感谢贾斯汀:

    #!/bin/bash
    
    ################################################## #########
    # Bash script to find which OS
    ################################################## #########
    
    OS=`uname`
    echo "$OS"
    

    source