How to check if running in Cygwin, Mac or Linux?

后端 未结 11 834
忘掉有多难
忘掉有多难 2020-11-27 23:58

I have a shell script that is used both on Windows/Cygwin and Mac and Linux. It needs slightly different variables for each versions.

How can a shell/bash script de

相关标签:
11条回答
  • 2020-11-28 00:57

    Bash sets the shell variable OSTYPE. From man bash:

    Automatically set to a string that describes the operating system on which bash is executing.

    This has a tiny advantage over uname in that it doesn't require launching a new process, so will be quicker to execute.

    However, I'm unable to find an authoritative list of expected values. For me on Ubuntu 14.04 it is set to 'linux-gnu'. I've scraped the web for some other values. Hence:

    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
    

    The asterisks are important in some instances - for example OSX appends an OS version number after the 'darwin'. The 'win' value is actually 'win32', I'm told - maybe there is a 'win64'?

    Perhaps we could work together to populate a table of verified values here:

    • Linux Ubuntu (incl. WSL): linux-gnu
    • Cygwin 64-bit: cygwin
    • Msys/MINGW (Git Bash for Windows): msys

    (Please append your value if it differs from existing entries)

    0 讨论(0)
  • 2020-11-28 00:58

    I guess the uname answer is unbeatable, mainly in terms of cleanliness.

    Although it takes a ridiculous time to execute, I found that testing for specific files presence also gives me good and quicker results, since I'm not invoking an executable:

    So,

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

    just uses a quick Bash file presence check. As I'm on Windows right now, I can't tell you any specific files for Linuxes and Mac OS X from my head, but I'm pretty sure they do exist. :-)

    0 讨论(0)
  • 2020-11-28 01:01

    To build upon Albert's answer, I like to use $COMSPEC for detecting 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
    

    This avoids parsing variants of Windows names for $OS, and parsing variants of uname like MINGW, Cygwin, etc.

    Background: %COMSPEC% is a Windows environmental variable specifying the full path to the command processor (aka the Windows shell). The value of this variable is typically %SystemRoot%\system32\cmd.exe, which typically evaluates to C:\Windows\system32\cmd.exe .

    0 讨论(0)
  • 2020-11-28 01:03

    Use uname -s (--kernel-name) because uname -o (--operating-system) is not supported on some Operating Systems such as Mac OS and Solaris. You may also use just uname without any argument since the default argument is -s (--kernel-name).

    The below snippet does not require bash (i.e. does not require #!/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
    

    The below Makefile is inspired from 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
    ...
    

    See also this complete answer about uname -s and Makefile.

    The correspondence table in the bottom of this answer is from Wikipedia article about uname. Please contribute to keep it up-to-date (edit the answer or post a comment). You may also update the Wikipedia article and post a comment to notify me about your contribution ;-)

    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
    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_SV
    (SCO) UnixWare UnixWare
    IBM AIX AIX
    IBM i with QSH OS400
    HP-UX HP-UX

    0 讨论(0)
  • 2020-11-28 01:05

    Use only this from command line works very fine, thanks to Justin:

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

    source

    0 讨论(0)
提交回复
热议问题