如何借助 Bash 脚本知道运行平台是 Ubuntu 还是 CentOS?

she*_*har 55 command-line bash scripts

我知道检查在我的机器上运行的 Linux 机器名称的命令。例如:

Ubuntu

cat /etc/version
Run Code Online (Sandbox Code Playgroud)

CentOS

cat /etc/issue
Run Code Online (Sandbox Code Playgroud)

如何从终端获取输出并比较看是UBUNTU还是CENTOS并执行以下命令?

apt-get install updates 
Run Code Online (Sandbox Code Playgroud)

或者

yum update
Run Code Online (Sandbox Code Playgroud)

Ubuntu 14.04

cat /etc/issue
Run Code Online (Sandbox Code Playgroud)

ter*_*don 73

不幸的是,没有可靠的、简单的方法来获取发行版名称。大多数主要发行版都在朝着一个他们/etc/os-release用来存储这些信息的系统发展。大多数现代发行版也包含这些lsb_release工具,但默认情况下并不总是安装这些工具。因此,您可以使用以下一些方法:

  1. /etc/os-release

    awk -F= '/^NAME/{print $2}' /etc/os-release
    
    Run Code Online (Sandbox Code Playgroud)
  2. lsb_release如果可用,请使用工具

    lsb_release -d | awk -F"\t" '{print $2}'
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用更复杂的脚本应该适用于绝大多数发行版:

    # Determine OS platform
    UNAME=$(uname | tr "[:upper:]" "[:lower:]")
    # If Linux, try to determine specific distribution
    if [ "$UNAME" == "linux" ]; then
        # If available, use LSB to identify distribution
        if [ -f /etc/lsb-release -o -d /etc/lsb-release.d ]; then
            export DISTRO=$(lsb_release -i | cut -d: -f2 | sed s/'^\t'//)
        # Otherwise, use release info file
        else
            export DISTRO=$(ls -d /etc/[A-Za-z]*[_-][rv]e[lr]* | grep -v "lsb" | cut -d'/' -f3 | cut -d'-' -f1 | cut -d'_' -f1)
        fi
    fi
    # For everything else (or if above failed), just use generic identifier
    [ "$DISTRO" == "" ] && export DISTRO=$UNAME
    unset UNAME
    
    Run Code Online (Sandbox Code Playgroud)
  4. 解析gcc如果安装的版本信息:

    CentOS 5.x

    $ gcc --version
    gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-54)
    Copyright (C) 2006 Free Software Foundation, Inc.
    
    Run Code Online (Sandbox Code Playgroud)

    CentOS 6.x

    $ gcc --version
    gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)
    Copyright (C) 2010 Free Software Foundation, Inc.
    
    Run Code Online (Sandbox Code Playgroud)

    Ubuntu 12.04

    $ gcc --version
    gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
    Copyright (C) 2011 Free Software Foundation, Inc.
    
    Run Code Online (Sandbox Code Playgroud)

    Ubuntu 14.04

    $ gcc --version
    gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
    Copyright (C) 2013 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    Run Code Online (Sandbox Code Playgroud)

这基本上是直接从@slm在这里对我的问题的精彩回答中直接复制的。


Syl*_*eau 27

你不需要 bash 来完成这样的任务,我建议使用高级方法来避免处理像/etc/version/etc/issue这样的文件(我在 13.10 上没有 /etc/version)。

所以我的建议是改用这个命令:

python -mplatform | grep -qi Ubuntu && sudo apt-get update || sudo yum update
Run Code Online (Sandbox Code Playgroud)

python平台模块将在两个系统上工作,命令的其余部分将检查 Ubuntu 是否由 python 返回并运行apt-getelse yum

  • 这似乎不再适用于 Ubuntu 20.04(我得到了 `Linux-5.4.0-26-generic-x86_64-with-glibc2.29`)。 (3认同)

小智 9

这是一个简单的答案,我发现仅通过文件的存在就可以在所有版本的 Ubuntu / CentOS / RHEL 上工作(当然,如果有人在您的 Ubuntu 机器上随机删除 /etc/redhat-release 等,则不是故障安全的):

if [ -f /etc/redhat-release ]; then
  yum update
fi

if [ -f /etc/lsb-release ]; then
  apt-get update
fi
Run Code Online (Sandbox Code Playgroud)

  • 我不会选择 -1,但这个答案至少在一种情况下是不正确的:`/etc/lsb-release` 存在于 CloudLinux (CentOS) 6.8 上,因此它将同时返回 `yum` 和 `apt-get` . (3认同)

Har*_*ris 8

在内核名称中检查 Ubuntu:

if [  -n "$(uname -a | grep Ubuntu)" ]; then
    sudo apt-get update && sudo apt-get upgrade 
else
    yum update
fi  
Run Code Online (Sandbox Code Playgroud)


小智 7

为此目的,该lsb_release命令被添加到 Linux 标准库 (ISO/IEC 23360) 中:

$ lsb_release -si
Ubuntu
$ lsb_release -sd
Ubuntu 18.04.3 LTS
$ lsb_release -sr
18.04
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:        18.04
Codename:       bionic
Run Code Online (Sandbox Code Playgroud)

因此,案例陈述大致如下

case "`/usr/bin/lsb_release -si`" in
  Ubuntu) echo 'This is Ubuntu Linux' ;;
       *) echo 'This is something else' ;; 
esac
Run Code Online (Sandbox Code Playgroud)

应该做你想做的事。

在基于 systemd 的较新 Linux 发行版上,还有/etc/os-release,旨在使用 source (.) 命令将其包含到 shell 脚本中,如下所示

. /etc/os-release

case "$ID" in
  ubuntu) echo 'This is Ubuntu Linux' ;;
       *) echo 'This is something else' ;; 
esac

Run Code Online (Sandbox Code Playgroud)

但在您给出的用例示例中,您实际上可能更感兴趣的不是发行版的名称,而是它是否具有apt-getyum. 您可以只测试文件是否存在/usr/bin/apt-get/usr/bin/yumwith if [ -x /usr/bin/apt-get ]; then... 或关联的基础结构目录是否存在,例如/var/lib/apt/etc/apt/


小智 6

 apt-get -v &> /dev/null && apt-get update
 which yum &> /dev/null && yum update
Run Code Online (Sandbox Code Playgroud)

如果只有两个发行版,那么您可以缩短它:

apt-get -v &> /dev/null && apt-get update || yum update
Run Code Online (Sandbox Code Playgroud)

yum -v在 CentOS 中以某种方式返回非零,因此请which改用,
当然如果没有which安装,您应该考虑场景。


小智 5

使用Chef来完成这些任务。;-)

在 Chef 中,您可以使用以下platform?方法:

if platform?("redhat", "centos", "fedora")
  # Code for only Red Hat Linux family systems.
end
Run Code Online (Sandbox Code Playgroud)

或者:

if platform?("ubuntu")
  # Code for only Ubuntu systems
end
Run Code Online (Sandbox Code Playgroud)

或者:

if platform?("ubuntu")
  # Do Ubuntu things
end
Run Code Online (Sandbox Code Playgroud)

或者:

if platform?("freebsd", "openbsd")
  # Do BSD things
end
Run Code Online (Sandbox Code Playgroud)