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

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


当前回答

检测三种不同的操作系统类型(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(雪豹)没有expr程序,除非你安装它,所以我只是使用uname。

设计

使用uname获取系统信息(-s参数)。 使用expr和substr来处理字符串。 使用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 Snow Leopard)测试正常。 Windows (Windows 7 64位)测试正常。

我学到了什么

检查开头和结尾的引号。 检查是否缺少括号和大括号{}

参考文献

[1] uname - wikipedia [2] shell脚本语法错误:文件意外结束 [3] Bash脚本检测操作系统 [4] BASH编程介绍

其他回答

我想无名的答案是无敌的,主要是在清洁方面。

虽然执行它需要很长时间,但我发现测试特定文件的存在也会给我更好和更快的结果,因为我没有调用可执行文件:

So,

[-f /usr/bin/cygwin1.dll] && echo是的,Cygwin正在运行

只是使用一个快速的Bash文件存在检查。因为我现在使用的是Windows,所以我无法告诉你任何linux和Mac OS X的具体文件,但我非常确定它们确实存在。: -)

# 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

检测三种不同的操作系统类型(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(雪豹)没有expr程序,除非你安装它,所以我只是使用uname。

设计

使用uname获取系统信息(-s参数)。 使用expr和substr来处理字符串。 使用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 Snow Leopard)测试正常。 Windows (Windows 7 64位)测试正常。

我学到了什么

检查开头和结尾的引号。 检查是否缺少括号和大括号{}

参考文献

[1] uname - wikipedia [2] shell脚本语法错误:文件意外结束 [3] Bash脚本检测操作系统 [4] BASH编程介绍

好的,这是我的方法。

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
}

我在我的dotfiles中使用这个

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

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

这意味着您需要使用uname -r来将其与本地Linux区分开来。