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

后端 未结 11 833
忘掉有多难
忘掉有多难 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:48

    Usually, uname with its various options will tell you what environment you're running in:

    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
    

    And, according to the very helpful schot (in the comments), uname -s gives Darwin for OSX and Linux for Linux, while my Cygwin gives CYGWIN_NT-5.1. But you may have to experiment with all sorts of different versions.

    So the bash code to do such a check would be along the lines of:

    unameOut="$(uname -s)"
    case "${unameOut}" in
        Linux*)     machine=Linux;;
        Darwin*)    machine=Mac;;
        CYGWIN*)    machine=Cygwin;;
        MINGW*)     machine=MinGw;;
        *)          machine="UNKNOWN:${unameOut}"
    esac
    echo ${machine}
    

    Note that I'm assuming here that you're actually running within CygWin (the bash shell of it) so paths should already be correctly set up. As one commenter notes, you can run the bash program, passing the script, from cmd itself and this may result in the paths not being set up as needed.

    If you are doing that, it's your responsibility to ensure the correct executables (i.e., the CygWin ones) are being called, possibly by modifying the path beforehand or fully specifying the executable locations (e.g., /c/cygwin/bin/uname).

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

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

    All the info you'll ever need. Google is your friend.

    Use uname -s to query the system name.

    • Mac: Darwin
    • Cygwin: CYGWIN_...
    • Linux: various, LINUX for most
    0 讨论(0)
  • 2020-11-28 00:51

    Here is the bash script I used to detect three different OS type (GNU/Linux, Mac OS X, Windows NT)

    Pay attention

    • In your bash script, use #!/usr/bin/env bash instead of #!/bin/sh to prevent the problem caused by /bin/sh linked to different default shell in different platforms, or there will be error like unexpected operator, that's what happened on my computer (Ubuntu 64 bits 12.04).
    • Mac OS X 10.6.8 (Snow Leopard) do not have expr program unless you install it, so I just use uname.

    Design

    1. Use uname to get the system information (-s parameter).
    2. Use expr and substr to deal with the string.
    3. Use if elif fi to do the matching job.
    4. You can add more system support if you want, just follow the uname -s specification.

    Implementation

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

    Testing

    • Linux (Ubuntu 12.04 LTS, Kernel 3.2.0) tested OK.
    • OS X (10.6.8 Snow Leopard) tested OK.
    • Windows (Windows 7 64 bit) tested OK.

    What I learned

    1. Check for both opening and closing quotes.
    2. Check for missing parentheses and braces {}

    References

    • [1] uname - wikipedia
    • [2] shell script syntax error: unexpected end of file
    • [3] Detect the OS from a Bash script
    • [4] BASH Programming Introduction HOW-TO
    0 讨论(0)
  • 2020-11-28 00:51

    Ok, here is my way.

    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 ^ $? ))
    }
    

    e.g.

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

    I use this in my dotfiles

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

    Windows Subsystem for Linux did not exist when this question was asked. It gave these results in my test:

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

    This means that you need uname -r to distinguish it from native Linux.

    0 讨论(0)
  • 2020-11-28 00:54
    # This script fragment emits Cygwin rulez under bash/cygwin
    if [[ $(uname -s) == CYGWIN* ]];then
        echo Cygwin rulez
    else 
        echo Unix is king
    fi
    

    If the 6 first chars of uname -s command is "CYGWIN", a cygwin system is assumed

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