如何从Bash脚本中检测操作系统?

时间:2022-03-20 01:42:42

I would like to keep my .bashrc and .bash_login files in version control so that I can use them between all the computers I use. The problem is I have some OS specific aliases so I was looking for a way to determine if the script is running on Mac OS X, Linux or Cygwin.

我想将.bashrc和.bash_login文件保存在版本控制中,以便我可以在我使用的所有计算机之间使用它们。问题是我有一些操作系统特定的别名,所以我一直在寻找一种方法来确定脚本是否在Mac OS X,Linux或Cygwin上运行。

What is the proper way to detect the operating system in a Bash script?

在Bash脚本中检测操作系统的正确方法是什么?

21 个解决方案

#1


I think the following should work. I'm not sure about win32 though.

我认为以下内容应该有效。我不确定win32。

if [[ "$OSTYPE" == "linux-gnu" ]]; then
        # ...
elif [[ "$OSTYPE" == "darwin"* ]]; then
        # Mac OSX
elif [[ "$OSTYPE" == "cygwin" ]]; then
        # POSIX compatibility layer and Linux environment emulation for Windows
elif [[ "$OSTYPE" == "msys" ]]; then
        # Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
elif [[ "$OSTYPE" == "win32" ]]; then
        # I'm not sure this can happen.
elif [[ "$OSTYPE" == "freebsd"* ]]; then
        # ...
else
        # Unknown.
fi

#2


For my .bashrc, I use the following code:

对于我的.bashrc,我使用以下代码:

platform='unknown'
unamestr=`uname`
if [[ "$unamestr" == 'Linux' ]]; then
   platform='linux'
elif [[ "$unamestr" == 'FreeBSD' ]]; then
   platform='freebsd'
fi

Then I do somethings like:

然后我做的事情如下:

if [[ $platform == 'linux' ]]; then
   alias ls='ls --color=auto'
elif [[ $platform == 'freebsd' ]]; then
   alias ls='ls -G'
fi

It's ugly, but it works. You may use case instead of if if you prefer.

这很难看,但它确实有效。如果您愿意,可以使用案例而不是。

#3


The bash manpage says that the variable OSTYPE stores the name of the operation system:

bash手册页说变量OSTYPE存储操作系统的名称:

OSTYPE Automatically set to a string that describes the operating system on which bash is executing. The default is system- dependent.

OSTYPE自动设置为一个字符串,描述执行bash的操作系统。默认值取决于系统。

It is set to linux-gnu here.

它在这里设置为linux-gnu。

#4


You can simply use pre-defined $OSTYPE variable ie.:

您可以简单地使用预定义的$ OSTYPE变量即:

case "$OSTYPE" in
  solaris*) echo "SOLARIS" ;;
  darwin*)  echo "OSX" ;; 
  linux*)   echo "LINUX" ;;
  bsd*)     echo "BSD" ;;
  msys*)    echo "WINDOWS" ;;
  *)        echo "unknown: $OSTYPE" ;;
esac

Another method is to detect platform based on uname command.

另一种方法是基于uname命令检测平台。

See the following script (ready to include in .bashrc):

请参阅以下脚本(准备包含在.bashrc中):

# Detect the platform (similar to $OSTYPE)
OS="`uname`"
case $OS in
  'Linux')
    OS='Linux'
    alias ls='ls --color=auto'
    ;;
  'FreeBSD')
    OS='FreeBSD'
    alias ls='ls -G'
    ;;
  'WindowsNT')
    OS='Windows'
    ;;
  'Darwin') 
    OS='Mac'
    ;;
  'SunOS')
    OS='Solaris'
    ;;
  'AIX') ;;
  *) ;;
esac

You can find some practical example in my .bashrc.

你可以在我的.bashrc中找到一些实际的例子。

#5


Detecting operating system and CPU type is not so easy to do portably. I have a sh script of about 100 lines that works across a very wide variety of Unix platforms: any system I have used since 1988.

检测操作系统和CPU类型并不容易移植。我有一个大约100行的sh脚本,适用于各种各样的Unix平台:自1988年以来我使用过的任何系统。

The key elements are

关键要素是

  • uname -p is processor type but is usually unknown on modern Unix platforms.

    uname -p是处理器类型,但在现代Unix平台上通常是未知的。

  • uname -m will give the "machine hardware name" on some Unix systems.

    uname -m将在某些Unix系统上提供“机器硬件名称”。

  • /bin/arch, if it exists, will usually give the type of processor.

    / bin / arch,如果存在,通常会给出处理器的类型。

  • uname with no arguments will name the operating system.

    没有参数的uname将命名操作系统。

Eventually you will have to think about the distinctions between platforms and how fine you want to make them. For example, just to keep things simple, I treat i386 through i686 , any "Pentium*" and any "AMD*Athlon*" all as x86.

最终,您将不得不考虑平台之间的区别以及您想要制作它们的精确程度。例如,为了简单起见,我将i386通过i686,任何“Pentium *”和任何“AMD * Athlon *”都视为x86。

My ~/.profile runs an a script at startup which sets one variable to a string indicating the combination of CPU and operating system. I have platform-specific bin, man, lib, and include directories that get set up based on that. Then I set a boatload of environment variables. So for example, a shell script to reformat mail can call, e.g., $LIB/mailfmt which is a platform-specific executable binary.

我的〜/ .profile在启动时运行一个脚本,它将一个变量设置为一个字符串,表示CPU和操作系统的组合。我有基于特定于平台的bin,man,lib和include目录。然后我设置了一大堆环境变量。因此,例如,重新格式化邮件的shell脚本可以调用例如$ LIB / mailfmt,这是特定于平台的可执行二进制文件。

If you want to cut corners, uname -m and plain uname will tell you what you want to know on many platforms. Add other stuff when you need it. (And use case, not nested if!)

如果你想偷工减料,uname -m和uname uname会告诉你在许多平台上你想知道什么。在需要时添加其他东西。 (和用例,如果没有嵌套!)

#6


I recommend to use this complete bash code

我建议使用这个完整的bash代码

lowercase(){
    echo "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
}

OS=`lowercase \`uname\``
KERNEL=`uname -r`
MACH=`uname -m`

if [ "{$OS}" == "windowsnt" ]; then
    OS=windows
elif [ "{$OS}" == "darwin" ]; then
    OS=mac
else
    OS=`uname`
    if [ "${OS}" = "SunOS" ] ; then
        OS=Solaris
        ARCH=`uname -p`
        OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
    elif [ "${OS}" = "AIX" ] ; then
        OSSTR="${OS} `oslevel` (`oslevel -r`)"
    elif [ "${OS}" = "Linux" ] ; then
        if [ -f /etc/redhat-release ] ; then
            DistroBasedOn='RedHat'
            DIST=`cat /etc/redhat-release |sed s/\ release.*//`
            PSUEDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
            REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
        elif [ -f /etc/SuSE-release ] ; then
            DistroBasedOn='SuSe'
            PSUEDONAME=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
            REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
        elif [ -f /etc/mandrake-release ] ; then
            DistroBasedOn='Mandrake'
            PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
            REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
        elif [ -f /etc/debian_version ] ; then
            DistroBasedOn='Debian'
            DIST=`cat /etc/lsb-release | grep '^DISTRIB_ID' | awk -F=  '{ print $2 }'`
            PSUEDONAME=`cat /etc/lsb-release | grep '^DISTRIB_CODENAME' | awk -F=  '{ print $2 }'`
            REV=`cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F=  '{ print $2 }'`
        fi
        if [ -f /etc/UnitedLinux-release ] ; then
            DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
        fi
        OS=`lowercase $OS`
        DistroBasedOn=`lowercase $DistroBasedOn`
        readonly OS
        readonly DIST
        readonly DistroBasedOn
        readonly PSUEDONAME
        readonly REV
        readonly KERNEL
        readonly MACH
    fi

fi

more examples examples here: https://github.com/coto/server-easy-install/blob/master/lib/core.sh

更多示例示例:https://github.com/coto/server-easy-install/blob/master/lib/core.sh

#7


In bash, use $OSTYPE and $HOSTTYPE, as documented; this is what I do. If that is not enough, and if even uname or uname -a (or other appropriate options) does not give enough information, there’s always the config.guess script from the GNU project, made exactly for this purpose.

在bash中,使用$ OSTYPE和$ HOSTTYPE,如文档所述;这就是我的工作。如果这还不够,即使uname或uname -a(或其他适当的选项)没有提供足够的信息,总会有GNU项目中的config.guess脚本完全用于此目的。

#8


Try using "uname". For example, in Linux: "uname -a".

尝试使用“uname”。例如,在Linux中:“uname -a”。

According to the manual page, uname conforms to SVr4 and POSIX, so it should be available on Mac OS X and Cygwin too, but I can't confirm that.

根据手册页,uname符合SVr4和POSIX,因此它也应该在Mac OS X和Cygwin上可用,但我无法确认。

BTW: $OSTYPE is also set to linux-gnu here :)

BTW:$ OSTYPE也设置为linux-gnu :)

#9


I would suggest avoiding some of these answers. Don't forget that you can choose other forms of string comparison, which would clear up most of the variations, or ugly code offered.

我建议避免一些这些答案。不要忘记您可以选择其他形式的字符串比较,这将清除大多数变体或提供的丑陋代码。

One such solution would be a simple check, such as:

一个这样的解决方案是简单的检查,例如:

if [[ "$OSTYPE" =~ ^darwin ]]; then

if [[“$ OSTYPE”=〜^ darwin]];然后

Which has the added benefit of matching any version of Darwin, despite it's version suffix. This also works for any variations of Linux one may expect.

除了版本后缀之外,它还具有匹配任何版本的Darwin的额外好处。这也适用于人们可能期望的任何Linux变体。

You can see some additional examples within my dotfiles here

您可以在我的dotfiles中看到一些其他示例

#10


I wrote these sugars in my .bashrc:

我在.bashrc中写了这些糖:

if_os () { [[ $OSTYPE == *$1* ]]; }
if_nix () { 
    case "$OSTYPE" in
        *linux*|*hurd*|*msys*|*cygwin*|*sua*|*interix*) sys="gnu";;
        *bsd*|*darwin*) sys="bsd";;
        *sunos*|*solaris*|*indiana*|*illumos*|*smartos*) sys="sun";;
    esac
    [[ "${sys}" == "$1" ]];
}

So I can do stuff like:

所以我可以这样做:

if_nix gnu && alias ls='ls --color=auto' && export LS_COLORS="..."
if_nix bsd && export CLICOLORS=on && export LSCOLORS="..."
if_os linux && alias psg="ps -FA | grep" #alternative to pgrep
if_nix bsd && alias psg="ps -alwx | grep -i" #alternative to pgrep
if_os darwin && alias finder="open -R"

#11


uname

or

uname -a

if you want more information

如果你想了解更多信息

#12


I wrote a personal Bash library and scripting framework that uses GNU shtool to do a rather accurate platform detection.

我编写了一个个人Bash库和脚本框架,它使用GNU shtool进行相当准确的平台检测。

GNU shtool is a very portable set of scripts that contains, among other useful things, the 'shtool platform' command. Here is the output of:

GNU shtool是一组非常便携的脚本,除了其他有用的东西外,还包含'shtool platform'命令。这是输出:

shtool platform -v -F "%sc (%ac) %st (%at) %sp (%ap)"

on a few different machines:

在几台不同的机器上:

Mac OS X Leopard: 
    4.4BSD/Mach3.0 (iX86) Apple Darwin 9.6.0 (i386) Apple Mac OS X 10.5.6 (iX86)

Ubuntu Jaunty server:
    LSB (iX86) GNU/Linux 2.9/2.6 (i686) Ubuntu 9.04 (iX86)

Debian Lenny:
    LSB (iX86) GNU/Linux 2.7/2.6 (i686) Debian GNU/Linux 5.0 (iX86)

This produces pretty satisfactory results, as you can see. GNU shtool is a little slow, so I actually store and update the platform identification in a file on the system that my scripts call. It's my framework, so that works for me, but your mileage may vary.

如您所见,这会产生非常令人满意的结果。 GNU shtool有点慢,所以我实际上在我脚本调用的系统上的文件中存储和更新平台标识。这是我的框架,所以这对我有用,但你的里程可能会有所不同。

Now, you'll have to find a way to package shtool with your scripts, but it's not a hard exercise. You can always fall back on uname output, also.

现在,您必须找到一种方法来使用脚本打包shtool,但这并不是一项艰苦的练习。你也总是可以依靠uname输出。

EDIT:

I missed the post by Teddy about config.guess (somehow). These are very similar scripts, but not the same. I personally use shtool for other uses as well, and it has been working quite well for me.

我错过了Teddy关于config.guess的帖子(不知何故)。这些是非常相似的脚本,但不一样。我个人也将shtool用于其他用途,它对我来说一直很好用。

#13


This should be safe to use on all distros.

这应该可以安全地用于所有发行版。

$ cat /etc/*release

This produces something like this.

这产生了这样的东西。

     DISTRIB_ID=LinuxMint
     DISTRIB_RELEASE=17
     DISTRIB_CODENAME=qiana
     DISTRIB_DESCRIPTION="Linux Mint 17 Qiana"
     NAME="Ubuntu"
     VERSION="14.04.1 LTS, Trusty Tahr"
     ID=ubuntu
     ID_LIKE=debian
     PRETTY_NAME="Ubuntu 14.04.1 LTS"
     VERSION_ID="14.04"
     HOME_URL="http://www.ubuntu.com/"
     SUPPORT_URL="http://help.ubuntu.com/"
     BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

Extract/assign to variables as you wish

根据需要提取/分配变量

Note: On some setups. This may also give you some errors that you can ignore.

注意:在某些设置上。这也可能会给您一些您可以忽略的错误。

     cat: /etc/upstream-release: Is a directory

#14


Below it's an approach to detect Debian and RedHat based Linux OS making use of the /etc/lsb-release and /etc/os-release (depending on the Linux flavor you're using) and take a simple action based on it.

下面是一种检测基于Debian和RedHat的Linux操作系统的方法,它使用/ etc / lsb-release和/ etc / os-release(取决于你正在使用的Linux风格)并采取基于它的简单操作。

#!/bin/bash
set -e

YUM_PACKAGE_NAME="python python-devl python-pip openssl-devel"
DEB_PACKAGE_NAME="python2.7 python-dev python-pip libssl-dev"

 if cat /etc/*release | grep ^NAME | grep CentOS; then
    echo "==============================================="
    echo "Installing packages $YUM_PACKAGE_NAME on CentOS"
    echo "==============================================="
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Red; then
    echo "==============================================="
    echo "Installing packages $YUM_PACKAGE_NAME on RedHat"
    echo "==============================================="
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Fedora; then
    echo "================================================"
    echo "Installing packages $YUM_PACKAGE_NAME on Fedorea"
    echo "================================================"
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Ubuntu; then
    echo "==============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Ubuntu"
    echo "==============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Debian ; then
    echo "==============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Debian"
    echo "==============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Mint ; then
    echo "============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Mint"
    echo "============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Knoppix ; then
    echo "================================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Kanoppix"
    echo "================================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 else
    echo "OS NOT DETECTED, couldn't install package $PACKAGE"
    exit 1;
 fi

exit 0

Output example for Ubuntu Linux:

Ubuntu Linux的输出示例:

delivery@delivery-E5450$ sudo sh detect_os.sh
[sudo] password for delivery: 
NAME="Ubuntu"
===============================================
Installing packages python2.7 python-dev python-pip libssl-dev on Ubuntu
===============================================
Ign http://dl.google.com stable InRelease
Get:1 http://dl.google.com stable Release.gpg [916 B]                          
Get:2 http://dl.google.com stable Release [1.189 B] 
...            

#15


You can use the following:

您可以使用以下内容:

OS=$(uname -s)

then you can use OS variable in your script.

然后你可以在你的脚本中使用OS变量。

#16


Doing the following helped perform the check correctly for ubuntu:

执行以下操作有助于为ubuntu正确执行检查:

if [[ "$OSTYPE" =~ ^linux ]]; then
    sudo apt-get install <some-package>
fi

#17


I tend to keep my .bashrc and .bash_alias on a file share that all platforms can access. This is how I conquer the problem in my .bash_alias:

我倾向于将.bashrc和.bash_alias保存在所有平台都可以访问的文件共享上。这就是我在.bash_alias中克服问题的方法:

if [[ -f (name of share)/.bash_alias_$(uname) ]]; then
    . (name of share)/.bash_alias_$(uname)
fi

And I have for example a .bash_alias_Linux with:

我有一个.bash_alias_Linux,例如:

alias ls='ls --color=auto'

This way I keep platform specific and portable code separate, you can do the same for .bashrc

这样我将平台特定和可移植代码分开,你可以为.bashrc做同样的事情

#18


You can use following if clause and expand it as needed:

您可以使用以下if子句并根据需要进行扩展:

if [ "${OSTYPE//[0-9.]/}" == "darwin" ]
then
	aminute_ago="-v-1M"
elif  [ "${OSTYPE//[0-9.]/}" == "linux-gnu" ]
then
	aminute_ago="-d \"1 minute ago\""
fi

#19


I tried the above messages across a few Linux distros and found the following to work best for me. It’s a short, concise exact word answer that works for Bash on Windows as well.

我在几个Linux发行版上尝试了上述消息,发现以下内容最适合我。这是一个简短,简洁的单词答案,适用于Windows上的Bash。

OS=$(cat /etc/*release | grep ^NAME | tr -d 'NAME="') #$ echo $OS # Ubuntu

#20


This checks a bunch of known files to identfy if the linux distro is Debian or Ubunu, then it defaults to the $OSTYPE variable.

如果linux发行版是Debian或Ubunu,它会检查一堆已知文件以识别,然后它默认为$ OSTYPE变量。

os='Uknown'
unamestr="${OSTYPE//[0-9.]/}"
os=$( compgen -G "/etc/*release" > /dev/null  && cat /etc/*release | grep ^NAME | tr -d 'NAME="'  ||  echo "$unamestr")

echo "$os"

#21


try this:

DISTRO=$(cat /etc/*-release | grep -w NAME | cut -d= -f2 | tr -d '"')
echo "Determined platform: $DISTRO"

#1


I think the following should work. I'm not sure about win32 though.

我认为以下内容应该有效。我不确定win32。

if [[ "$OSTYPE" == "linux-gnu" ]]; then
        # ...
elif [[ "$OSTYPE" == "darwin"* ]]; then
        # Mac OSX
elif [[ "$OSTYPE" == "cygwin" ]]; then
        # POSIX compatibility layer and Linux environment emulation for Windows
elif [[ "$OSTYPE" == "msys" ]]; then
        # Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
elif [[ "$OSTYPE" == "win32" ]]; then
        # I'm not sure this can happen.
elif [[ "$OSTYPE" == "freebsd"* ]]; then
        # ...
else
        # Unknown.
fi

#2


For my .bashrc, I use the following code:

对于我的.bashrc,我使用以下代码:

platform='unknown'
unamestr=`uname`
if [[ "$unamestr" == 'Linux' ]]; then
   platform='linux'
elif [[ "$unamestr" == 'FreeBSD' ]]; then
   platform='freebsd'
fi

Then I do somethings like:

然后我做的事情如下:

if [[ $platform == 'linux' ]]; then
   alias ls='ls --color=auto'
elif [[ $platform == 'freebsd' ]]; then
   alias ls='ls -G'
fi

It's ugly, but it works. You may use case instead of if if you prefer.

这很难看,但它确实有效。如果您愿意,可以使用案例而不是。

#3


The bash manpage says that the variable OSTYPE stores the name of the operation system:

bash手册页说变量OSTYPE存储操作系统的名称:

OSTYPE Automatically set to a string that describes the operating system on which bash is executing. The default is system- dependent.

OSTYPE自动设置为一个字符串,描述执行bash的操作系统。默认值取决于系统。

It is set to linux-gnu here.

它在这里设置为linux-gnu。

#4


You can simply use pre-defined $OSTYPE variable ie.:

您可以简单地使用预定义的$ OSTYPE变量即:

case "$OSTYPE" in
  solaris*) echo "SOLARIS" ;;
  darwin*)  echo "OSX" ;; 
  linux*)   echo "LINUX" ;;
  bsd*)     echo "BSD" ;;
  msys*)    echo "WINDOWS" ;;
  *)        echo "unknown: $OSTYPE" ;;
esac

Another method is to detect platform based on uname command.

另一种方法是基于uname命令检测平台。

See the following script (ready to include in .bashrc):

请参阅以下脚本(准备包含在.bashrc中):

# Detect the platform (similar to $OSTYPE)
OS="`uname`"
case $OS in
  'Linux')
    OS='Linux'
    alias ls='ls --color=auto'
    ;;
  'FreeBSD')
    OS='FreeBSD'
    alias ls='ls -G'
    ;;
  'WindowsNT')
    OS='Windows'
    ;;
  'Darwin') 
    OS='Mac'
    ;;
  'SunOS')
    OS='Solaris'
    ;;
  'AIX') ;;
  *) ;;
esac

You can find some practical example in my .bashrc.

你可以在我的.bashrc中找到一些实际的例子。

#5


Detecting operating system and CPU type is not so easy to do portably. I have a sh script of about 100 lines that works across a very wide variety of Unix platforms: any system I have used since 1988.

检测操作系统和CPU类型并不容易移植。我有一个大约100行的sh脚本,适用于各种各样的Unix平台:自1988年以来我使用过的任何系统。

The key elements are

关键要素是

  • uname -p is processor type but is usually unknown on modern Unix platforms.

    uname -p是处理器类型,但在现代Unix平台上通常是未知的。

  • uname -m will give the "machine hardware name" on some Unix systems.

    uname -m将在某些Unix系统上提供“机器硬件名称”。

  • /bin/arch, if it exists, will usually give the type of processor.

    / bin / arch,如果存在,通常会给出处理器的类型。

  • uname with no arguments will name the operating system.

    没有参数的uname将命名操作系统。

Eventually you will have to think about the distinctions between platforms and how fine you want to make them. For example, just to keep things simple, I treat i386 through i686 , any "Pentium*" and any "AMD*Athlon*" all as x86.

最终,您将不得不考虑平台之间的区别以及您想要制作它们的精确程度。例如,为了简单起见,我将i386通过i686,任何“Pentium *”和任何“AMD * Athlon *”都视为x86。

My ~/.profile runs an a script at startup which sets one variable to a string indicating the combination of CPU and operating system. I have platform-specific bin, man, lib, and include directories that get set up based on that. Then I set a boatload of environment variables. So for example, a shell script to reformat mail can call, e.g., $LIB/mailfmt which is a platform-specific executable binary.

我的〜/ .profile在启动时运行一个脚本,它将一个变量设置为一个字符串,表示CPU和操作系统的组合。我有基于特定于平台的bin,man,lib和include目录。然后我设置了一大堆环境变量。因此,例如,重新格式化邮件的shell脚本可以调用例如$ LIB / mailfmt,这是特定于平台的可执行二进制文件。

If you want to cut corners, uname -m and plain uname will tell you what you want to know on many platforms. Add other stuff when you need it. (And use case, not nested if!)

如果你想偷工减料,uname -m和uname uname会告诉你在许多平台上你想知道什么。在需要时添加其他东西。 (和用例,如果没有嵌套!)

#6


I recommend to use this complete bash code

我建议使用这个完整的bash代码

lowercase(){
    echo "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
}

OS=`lowercase \`uname\``
KERNEL=`uname -r`
MACH=`uname -m`

if [ "{$OS}" == "windowsnt" ]; then
    OS=windows
elif [ "{$OS}" == "darwin" ]; then
    OS=mac
else
    OS=`uname`
    if [ "${OS}" = "SunOS" ] ; then
        OS=Solaris
        ARCH=`uname -p`
        OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
    elif [ "${OS}" = "AIX" ] ; then
        OSSTR="${OS} `oslevel` (`oslevel -r`)"
    elif [ "${OS}" = "Linux" ] ; then
        if [ -f /etc/redhat-release ] ; then
            DistroBasedOn='RedHat'
            DIST=`cat /etc/redhat-release |sed s/\ release.*//`
            PSUEDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
            REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
        elif [ -f /etc/SuSE-release ] ; then
            DistroBasedOn='SuSe'
            PSUEDONAME=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
            REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
        elif [ -f /etc/mandrake-release ] ; then
            DistroBasedOn='Mandrake'
            PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
            REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
        elif [ -f /etc/debian_version ] ; then
            DistroBasedOn='Debian'
            DIST=`cat /etc/lsb-release | grep '^DISTRIB_ID' | awk -F=  '{ print $2 }'`
            PSUEDONAME=`cat /etc/lsb-release | grep '^DISTRIB_CODENAME' | awk -F=  '{ print $2 }'`
            REV=`cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F=  '{ print $2 }'`
        fi
        if [ -f /etc/UnitedLinux-release ] ; then
            DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
        fi
        OS=`lowercase $OS`
        DistroBasedOn=`lowercase $DistroBasedOn`
        readonly OS
        readonly DIST
        readonly DistroBasedOn
        readonly PSUEDONAME
        readonly REV
        readonly KERNEL
        readonly MACH
    fi

fi

more examples examples here: https://github.com/coto/server-easy-install/blob/master/lib/core.sh

更多示例示例:https://github.com/coto/server-easy-install/blob/master/lib/core.sh

#7


In bash, use $OSTYPE and $HOSTTYPE, as documented; this is what I do. If that is not enough, and if even uname or uname -a (or other appropriate options) does not give enough information, there’s always the config.guess script from the GNU project, made exactly for this purpose.

在bash中,使用$ OSTYPE和$ HOSTTYPE,如文档所述;这就是我的工作。如果这还不够,即使uname或uname -a(或其他适当的选项)没有提供足够的信息,总会有GNU项目中的config.guess脚本完全用于此目的。

#8


Try using "uname". For example, in Linux: "uname -a".

尝试使用“uname”。例如,在Linux中:“uname -a”。

According to the manual page, uname conforms to SVr4 and POSIX, so it should be available on Mac OS X and Cygwin too, but I can't confirm that.

根据手册页,uname符合SVr4和POSIX,因此它也应该在Mac OS X和Cygwin上可用,但我无法确认。

BTW: $OSTYPE is also set to linux-gnu here :)

BTW:$ OSTYPE也设置为linux-gnu :)

#9


I would suggest avoiding some of these answers. Don't forget that you can choose other forms of string comparison, which would clear up most of the variations, or ugly code offered.

我建议避免一些这些答案。不要忘记您可以选择其他形式的字符串比较,这将清除大多数变体或提供的丑陋代码。

One such solution would be a simple check, such as:

一个这样的解决方案是简单的检查,例如:

if [[ "$OSTYPE" =~ ^darwin ]]; then

if [[“$ OSTYPE”=〜^ darwin]];然后

Which has the added benefit of matching any version of Darwin, despite it's version suffix. This also works for any variations of Linux one may expect.

除了版本后缀之外,它还具有匹配任何版本的Darwin的额外好处。这也适用于人们可能期望的任何Linux变体。

You can see some additional examples within my dotfiles here

您可以在我的dotfiles中看到一些其他示例

#10


I wrote these sugars in my .bashrc:

我在.bashrc中写了这些糖:

if_os () { [[ $OSTYPE == *$1* ]]; }
if_nix () { 
    case "$OSTYPE" in
        *linux*|*hurd*|*msys*|*cygwin*|*sua*|*interix*) sys="gnu";;
        *bsd*|*darwin*) sys="bsd";;
        *sunos*|*solaris*|*indiana*|*illumos*|*smartos*) sys="sun";;
    esac
    [[ "${sys}" == "$1" ]];
}

So I can do stuff like:

所以我可以这样做:

if_nix gnu && alias ls='ls --color=auto' && export LS_COLORS="..."
if_nix bsd && export CLICOLORS=on && export LSCOLORS="..."
if_os linux && alias psg="ps -FA | grep" #alternative to pgrep
if_nix bsd && alias psg="ps -alwx | grep -i" #alternative to pgrep
if_os darwin && alias finder="open -R"

#11


uname

or

uname -a

if you want more information

如果你想了解更多信息

#12


I wrote a personal Bash library and scripting framework that uses GNU shtool to do a rather accurate platform detection.

我编写了一个个人Bash库和脚本框架,它使用GNU shtool进行相当准确的平台检测。

GNU shtool is a very portable set of scripts that contains, among other useful things, the 'shtool platform' command. Here is the output of:

GNU shtool是一组非常便携的脚本,除了其他有用的东西外,还包含'shtool platform'命令。这是输出:

shtool platform -v -F "%sc (%ac) %st (%at) %sp (%ap)"

on a few different machines:

在几台不同的机器上:

Mac OS X Leopard: 
    4.4BSD/Mach3.0 (iX86) Apple Darwin 9.6.0 (i386) Apple Mac OS X 10.5.6 (iX86)

Ubuntu Jaunty server:
    LSB (iX86) GNU/Linux 2.9/2.6 (i686) Ubuntu 9.04 (iX86)

Debian Lenny:
    LSB (iX86) GNU/Linux 2.7/2.6 (i686) Debian GNU/Linux 5.0 (iX86)

This produces pretty satisfactory results, as you can see. GNU shtool is a little slow, so I actually store and update the platform identification in a file on the system that my scripts call. It's my framework, so that works for me, but your mileage may vary.

如您所见,这会产生非常令人满意的结果。 GNU shtool有点慢,所以我实际上在我脚本调用的系统上的文件中存储和更新平台标识。这是我的框架,所以这对我有用,但你的里程可能会有所不同。

Now, you'll have to find a way to package shtool with your scripts, but it's not a hard exercise. You can always fall back on uname output, also.

现在,您必须找到一种方法来使用脚本打包shtool,但这并不是一项艰苦的练习。你也总是可以依靠uname输出。

EDIT:

I missed the post by Teddy about config.guess (somehow). These are very similar scripts, but not the same. I personally use shtool for other uses as well, and it has been working quite well for me.

我错过了Teddy关于config.guess的帖子(不知何故)。这些是非常相似的脚本,但不一样。我个人也将shtool用于其他用途,它对我来说一直很好用。

#13


This should be safe to use on all distros.

这应该可以安全地用于所有发行版。

$ cat /etc/*release

This produces something like this.

这产生了这样的东西。

     DISTRIB_ID=LinuxMint
     DISTRIB_RELEASE=17
     DISTRIB_CODENAME=qiana
     DISTRIB_DESCRIPTION="Linux Mint 17 Qiana"
     NAME="Ubuntu"
     VERSION="14.04.1 LTS, Trusty Tahr"
     ID=ubuntu
     ID_LIKE=debian
     PRETTY_NAME="Ubuntu 14.04.1 LTS"
     VERSION_ID="14.04"
     HOME_URL="http://www.ubuntu.com/"
     SUPPORT_URL="http://help.ubuntu.com/"
     BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

Extract/assign to variables as you wish

根据需要提取/分配变量

Note: On some setups. This may also give you some errors that you can ignore.

注意:在某些设置上。这也可能会给您一些您可以忽略的错误。

     cat: /etc/upstream-release: Is a directory

#14


Below it's an approach to detect Debian and RedHat based Linux OS making use of the /etc/lsb-release and /etc/os-release (depending on the Linux flavor you're using) and take a simple action based on it.

下面是一种检测基于Debian和RedHat的Linux操作系统的方法,它使用/ etc / lsb-release和/ etc / os-release(取决于你正在使用的Linux风格)并采取基于它的简单操作。

#!/bin/bash
set -e

YUM_PACKAGE_NAME="python python-devl python-pip openssl-devel"
DEB_PACKAGE_NAME="python2.7 python-dev python-pip libssl-dev"

 if cat /etc/*release | grep ^NAME | grep CentOS; then
    echo "==============================================="
    echo "Installing packages $YUM_PACKAGE_NAME on CentOS"
    echo "==============================================="
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Red; then
    echo "==============================================="
    echo "Installing packages $YUM_PACKAGE_NAME on RedHat"
    echo "==============================================="
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Fedora; then
    echo "================================================"
    echo "Installing packages $YUM_PACKAGE_NAME on Fedorea"
    echo "================================================"
    yum install -y $YUM_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Ubuntu; then
    echo "==============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Ubuntu"
    echo "==============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Debian ; then
    echo "==============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Debian"
    echo "==============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Mint ; then
    echo "============================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Mint"
    echo "============================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 elif cat /etc/*release | grep ^NAME | grep Knoppix ; then
    echo "================================================="
    echo "Installing packages $DEB_PACKAGE_NAME on Kanoppix"
    echo "================================================="
    apt-get update
    apt-get install -y $DEB_PACKAGE_NAME
 else
    echo "OS NOT DETECTED, couldn't install package $PACKAGE"
    exit 1;
 fi

exit 0

Output example for Ubuntu Linux:

Ubuntu Linux的输出示例:

delivery@delivery-E5450$ sudo sh detect_os.sh
[sudo] password for delivery: 
NAME="Ubuntu"
===============================================
Installing packages python2.7 python-dev python-pip libssl-dev on Ubuntu
===============================================
Ign http://dl.google.com stable InRelease
Get:1 http://dl.google.com stable Release.gpg [916 B]                          
Get:2 http://dl.google.com stable Release [1.189 B] 
...            

#15


You can use the following:

您可以使用以下内容:

OS=$(uname -s)

then you can use OS variable in your script.

然后你可以在你的脚本中使用OS变量。

#16


Doing the following helped perform the check correctly for ubuntu:

执行以下操作有助于为ubuntu正确执行检查:

if [[ "$OSTYPE" =~ ^linux ]]; then
    sudo apt-get install <some-package>
fi

#17


I tend to keep my .bashrc and .bash_alias on a file share that all platforms can access. This is how I conquer the problem in my .bash_alias:

我倾向于将.bashrc和.bash_alias保存在所有平台都可以访问的文件共享上。这就是我在.bash_alias中克服问题的方法:

if [[ -f (name of share)/.bash_alias_$(uname) ]]; then
    . (name of share)/.bash_alias_$(uname)
fi

And I have for example a .bash_alias_Linux with:

我有一个.bash_alias_Linux,例如:

alias ls='ls --color=auto'

This way I keep platform specific and portable code separate, you can do the same for .bashrc

这样我将平台特定和可移植代码分开,你可以为.bashrc做同样的事情

#18


You can use following if clause and expand it as needed:

您可以使用以下if子句并根据需要进行扩展:

if [ "${OSTYPE//[0-9.]/}" == "darwin" ]
then
	aminute_ago="-v-1M"
elif  [ "${OSTYPE//[0-9.]/}" == "linux-gnu" ]
then
	aminute_ago="-d \"1 minute ago\""
fi

#19


I tried the above messages across a few Linux distros and found the following to work best for me. It’s a short, concise exact word answer that works for Bash on Windows as well.

我在几个Linux发行版上尝试了上述消息,发现以下内容最适合我。这是一个简短,简洁的单词答案,适用于Windows上的Bash。

OS=$(cat /etc/*release | grep ^NAME | tr -d 'NAME="') #$ echo $OS # Ubuntu

#20


This checks a bunch of known files to identfy if the linux distro is Debian or Ubunu, then it defaults to the $OSTYPE variable.

如果linux发行版是Debian或Ubunu,它会检查一堆已知文件以识别,然后它默认为$ OSTYPE变量。

os='Uknown'
unamestr="${OSTYPE//[0-9.]/}"
os=$( compgen -G "/etc/*release" > /dev/null  && cat /etc/*release | grep ^NAME | tr -d 'NAME="'  ||  echo "$unamestr")

echo "$os"

#21


try this:

DISTRO=$(cat /etc/*-release | grep -w NAME | cut -d= -f2 | tr -d '"')
echo "Determined platform: $DISTRO"