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

发布于 2024-07-10 16:06:54 字数 352 浏览 9 评论 0 原文

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

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

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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(23

倾城°AllureLove 2024-07-17 16:06:54

我认为以下应该有效。 不过我不确定 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

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

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
我不是你的备胎 2024-07-17 16:06:54

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

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

然后我做类似的事情:

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

它很丑陋,但它有效。 如果您愿意,可以使用 case 代替 if

For my .bashrc, I use the following code:

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.

匿名的好友 2024-07-17 16:06:54

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

OSTYPE 自动设置为描述正在执行 bash 的操作系统的字符串。 默认是系统-
依赖。

这里设置为linux-gnu

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

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

It is set to linux-gnu here.

软糯酥胸 2024-07-17 16:06:54

$OSTYPE

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

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

但是它是 旧版 shell 无法识别(例如 Bourne shell)。


uname

另一种方法是根据检测平台uname命令。

请参阅以下脚本(准备包含在 .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

您可以在我的 .bashrc< 中找到一些实际示例/代码>


这是 Travis 上使用的类似版本CI

case $(uname | tr '[:upper:]' '[:lower:]') in
  linux*)
    export TRAVIS_OS_NAME=linux
    ;;
  darwin*)
    export TRAVIS_OS_NAME=osx
    ;;
  msys*)
    export TRAVIS_OS_NAME=windows
    ;;
  *)
    export TRAVIS_OS_NAME=notset
    ;;
esac

$OSTYPE

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

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

However it's not recognized by the older shells (such as Bourne shell).


uname

Another method is to detect platform based on uname command.

See the following script (ready to include in .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.


Here is similar version used on Travis CI:

case $(uname | tr '[:upper:]' '[:lower:]') in
  linux*)
    export TRAVIS_OS_NAME=linux
    ;;
  darwin*)
    export TRAVIS_OS_NAME=osx
    ;;
  msys*)
    export TRAVIS_OS_NAME=windows
    ;;
  *)
    export TRAVIS_OS_NAME=notset
    ;;
esac
日暮斜阳 2024-07-17 16:06:54

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

关键元素是

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

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

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

  • uname 不带参数将命名操作系统。

最终,您将不得不考虑平台之间的区别以及您希望将它们做得有多好。例如,为了简单起见,我将 i386 视为 i686 、任何“Pentium*”和任何“AMD*Athlon*”都为 x86

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

如果您想走捷径uname -m 和简单的 uname 会告诉您在许多平台上想知道的内容。 当你需要的时候添加其他东西。 (并使用 case,而不是嵌套 if!)

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.

The key elements are

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

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

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

  • uname with no arguments will name the operating system.

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.

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.

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!)

不…忘初心 2024-07-17 16:06:54

我建议使用这个完整的 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
echo $OS
echo $KERNEL
echo $MACH

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

I recommend to use this complete bash code

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
echo $OS
echo $KERNEL
echo $MACH

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

酒绊 2024-07-17 16:06:54

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

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

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

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

您可以在此处查看我的点文件中的一些其他示例

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

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.

You can see some additional examples within my dotfiles here

甜味拾荒者 2024-07-17 16:06:54

如果有人也有兴趣检测 WSL 与 WSL 版本 2,我会使用此方法。
这在 ZSH 和 BASH 中都有效。

#!/usr/bin/env bash

unameOut=$(uname -a)
case "${unameOut}" in
    *Microsoft*)     OS="WSL";; #must be first since Windows subsystem for linux will have Linux in the name too
    *microsoft*)     OS="WSL2";; #WARNING: My v2 uses ubuntu 20.4 at the moment slightly different name may not always work
    Linux*)     OS="Linux";;
    Darwin*)    OS="Mac";;
    CYGWIN*)    OS="Cygwin";;
    MINGW*)     OS="Windows";;
    *Msys)     OS="Windows";;
    *)          OS="UNKNOWN:${unameOut}"
esac

echo ${OS};

更新:我还将其添加到我的脚本中,用于检测 M1 与普通 Mac。

if [[ ${OS} == "Mac" ]] && sysctl -n machdep.cpu.brand_string | grep -q 'Apple M1'; then
    OS="MacM1"
fi

This is what I use if anyone is interested in detecting WSL vs WSL version 2 as well.
This works in ZSH as well as BASH.

#!/usr/bin/env bash

unameOut=$(uname -a)
case "${unameOut}" in
    *Microsoft*)     OS="WSL";; #must be first since Windows subsystem for linux will have Linux in the name too
    *microsoft*)     OS="WSL2";; #WARNING: My v2 uses ubuntu 20.4 at the moment slightly different name may not always work
    Linux*)     OS="Linux";;
    Darwin*)    OS="Mac";;
    CYGWIN*)    OS="Cygwin";;
    MINGW*)     OS="Windows";;
    *Msys)     OS="Windows";;
    *)          OS="UNKNOWN:${unameOut}"
esac

echo ${OS};

Update: I also added this to my script for detecting M1 vs a normal Mac.

if [[ ${OS} == "Mac" ]] && sysctl -n machdep.cpu.brand_string | grep -q 'Apple M1'; then
    OS="MacM1"
fi
灯角 2024-07-17 16:06:54
uname

或者

uname -a

如果您想了解更多信息

uname

or

uname -a

if you want more information

你好,陌生人 2024-07-17 16:06:54

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

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

顺便说一句:这里 $OSTYPE 也设置为 linux-gnu :)

Try using "uname". For example, in 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.

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

酒与心事 2024-07-17 16:06:54

在 bash 中,使用 $OSTYPE$HOSTTYPE,如文档所述; 这就是我所做的。 如果这还不够,并且即使 unameuname -a (或其他适当的选项)也没有提供足够的信息,那么总是有 config.guess 来自 GNU 的脚本项目,正是为此目的而制作的。

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.

说不完的你爱 2024-07-17 16:06:54

我在我的 .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" ]];
}

所以我可以做类似的事情:

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"

I wrote these sugars in my .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"
新人笑 2024-07-17 16:06:54

下面是一种利用 /etc/lsb-release 检测基于 Debian 和 RedHat 的 Linux OS 的方法/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

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] 
...            

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.

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

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] 
...            
执笔绘流年 2024-07-17 16:06:54

您可以使用以下内容:

OS=$(uname -s)

然后您可以在脚本中使用操作系统变量。

You can use the following:

OS=$(uname -s)

then you can use OS variable in your script.

咽泪装欢 2024-07-17 16:06:54

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

GNU shtool 是一组非常可移植的脚本,其中包含“shtool platform”命令等有用的内容。 这是以下输出:

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

在几台不同的机器上:

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)

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

现在,您必须找到一种将 shtool 与脚本打包在一起的方法,但这并不是一个困难的练习。 您也可以随时依靠 uname 输出。

编辑:

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

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

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

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.

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.

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.

温馨耳语 2024-07-17 16:06:54

尝试这个:

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

try this:

DISTRO=$(cat /etc/*-release | grep -w NAME | cut -d= -f2 | tr -d '"')
echo "Determined platform: $DISTRO"
咽泪装欢 2024-07-17 16:06:54

这应该可以在所有发行版上安全使用。

$ cat /etc/*release

这会产生类似这样的东西。

     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/"

根据需要提取/分配给变量

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

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

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
倾`听者〃 2024-07-17 16:06:54

您可以使用以下 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

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

if [ "${OSTYPE//[0-9.]/}" == "darwin" ]
then
    aminute_ago="-v-1M"
elif  [ "${OSTYPE//[0-9.]/}" == "linux-gnu" ]
then
    aminute_ago="-d \"1 minute ago\""
fi
疯了 2024-07-17 16:06:54

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

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

例如,我有一个 .bash_alias_Linux:

alias ls='ls --color=auto'

这样我可以将特定于平台的代码和可移植代码分开,您可以对 .bashrc 执行相同的操作

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:

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:

alias ls='ls --color=auto'

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

寄风 2024-07-17 16:06:54

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

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

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.

OS=$(cat /etc/*release | grep ^NAME | tr -d 'NAME="') #$ echo $OS # Ubuntu
舟遥客 2024-07-17 16:06:54

这会检查一堆已知文件来识别Linux发行版是否是Debian或Ubunu,然后它默认为$OSTYPE变量。

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

echo "$os"

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

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

echo "$os"
一影成城 2024-07-17 16:06:54

我只关心Windows和Linux(特别是:Linux Ubuntu),但我想要更多关于它们的信息,而不是这里的主要答案< /a>.

因此,这是我对主要答案的扩展,以提供有关您正在运行的 Linux 或 Windows 版本的更多详细信息

if [[ "$OSTYPE" == "linux-gnu"* ]]; then
    OPERATING_SYSTEM="Linux: $(lsb_release -d | cut -f2-)"
elif [[ "$OSTYPE" == "msys" ]]; then 
    OPERATING_SYSTEM="Windows: MSYS2: $(uname -a)"
fi

echo "OPERATING_SYSTEM = $OPERATING_SYSTEM"

在 Git Bash 中运行时的示例输出(来自 Git For Windows) 在 Windows 上:

OPERATING_SYSTEM = Windows: MSYS2: MINGW64_NT-10.0-19045 S-C0355 3.4.9-be826601.x86_64 2023-09-07 12:36 UTC x86_64 Msys

Linux Ubuntu 22.04 上的 Bash 终端的示例输出:

OPERATING_SYSTEM = Linux: Ubuntu 22.04.4 LTS

参考资料

  1. 我上面的代码片段解决方案是我的 Doxyfile_run_doxygen.sh 脚本https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles" rel="nofollow noreferrer">eRCaGuy_dotfiles 存储库。

进一步发展

  1. 以下是我的安装说明,旨在为您提供 Windows 中良好的 Bash 终端:
    1. 安装 Windows 版 Git
    2. 安装并安装 从头开始设置 MSYS2,包括将所有 7 个配置文件添加到 Windows 终端

I just care about Windows and Linux (specifically: Linux Ubuntu), but I want more information about them than is provided by the main answer here.

So, here's my extension of the main answer to provide more details about which version of Linux or Windows you are running:

if [[ "$OSTYPE" == "linux-gnu"* ]]; then
    OPERATING_SYSTEM="Linux: $(lsb_release -d | cut -f2-)"
elif [[ "$OSTYPE" == "msys" ]]; then 
    OPERATING_SYSTEM="Windows: MSYS2: $(uname -a)"
fi

echo "OPERATING_SYSTEM = $OPERATING_SYSTEM"

Example output when run in Git Bash (from Git For Windows) on Windows:

OPERATING_SYSTEM = Windows: MSYS2: MINGW64_NT-10.0-19045 S-C0355 3.4.9-be826601.x86_64 2023-09-07 12:36 UTC x86_64 Msys

Example output from a Bash terminal on Linux Ubuntu 22.04:

OPERATING_SYSTEM = Linux: Ubuntu 22.04.4 LTS

References

  1. My above code snippet solution was first part of my Doxyfile_run_doxygen.sh script in my eRCaGuy_dotfiles repo.

Going further

  1. Here are my installation instructions to give you good Bash terminals in Windows:
    1. Installing Git For Windows
    2. Installing & setting up MSYS2 from scratch, including adding all 7 profiles to Windows Terminal
等待我真够勒 2024-07-17 16:06:54

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

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

Doing the following helped perform the check correctly for ubuntu:

if [[ "$OSTYPE" =~ ^linux ]]; then
    sudo apt-get install <some-package>
fi
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文