识别各种操作系统名称与版本

126 阅读3分钟

编写shell获取对应的操作系统名称以及版本号可能是一个常规需求,要怎么做呢?

获取Ubunt/Centos7及以上系统名称和版本

# 命令获取系统版本信息
[root@nginx ~]# sed -nr "s#^PRETTY_NAME=\"(.*)\"#\1#p" /etc/os-release
CentOS Linux 7 (Core)
root@ubuntu1804:~# sed -nr "s#^PRETTY_NAME=\"(.*)\"#\1#p" /etc/os-release
Ubuntu 18.04.5 LTS

# 脚本开始
#!/bin/bash
# 使用source命令引入 /etc/os-release以后,所有输出项目都变为可直接使用的变量. centos7及以上版本都可以使用/etc/os-release文件判断系统版本, 但centos 6没有此文件因此不可以
os_version(){
  if [ -f /etc/os-release ]; then
       source /etc/os-release
  else
       echo "`cat /etc/redhat-release`"
  fi
}

# 需要通过判断系统版本执行不同的命令的函数
set_code(){
  if [[ $PRETTY_NAME =~ "Ubuntu 18.04" ]]; then
        echo "$PRETTY_NAME"
  elif [[ $PRETTY_NAME =~ "Rocky Linux 8" ]]; then
        echo "$PRETTY_NAME"
  elif [[ $PRETTY_NAME =~ "Kylin Linux Advanced Server V10" ]]; then
        echo "$PRETTY_NAME"
  elif [[ $PRETTY_NAME =~ "CentOS Linux 7" ]]; then
        echo "$PRETTY_NAME"
  elif [[ $PRETTY_NAME =~ "UnionTech OS Server 20" ]]; then
        echo "$PRETTY_NAME"
  fi
}
os_version
set_code
## 脚本结束


# 不同操作系统执行结果
┌─[root@k8s-master01]─09:53:08 [~]
└──╼ #bash version.sh
Ubuntu 18.04.5 LTS

┌─[root@zabbix.techcat.cc]─09:55:47 [~]
└──╼ #bash version.sh
CentOS Linux 7 (Core)

[root@localhost ~]# bash version.sh
Kylin Linux Advanced Server V10 (Lance)

[root@localhost ~]# bash version.sh
UnionTech OS Server 20

[root@harbor ~]# bash version.sh
Rocky Linux 8.5 (Green Obsidian)

获取各种操作系统名称与版本

根据Rust官方文档提供的代码修改而来:

# centos7及以上版本都可以使用/etc/os-release文件判断系统版本, 但centos 6没有此文件因此不可以. 使用source或者.命令引入 /etc/os-release以后,所有的项都变为可直接使用的变量. 
OS_VER (){
  # 识别操作系统版本
  if [ -f /etc/os-release ]; then
      # freedesktop.org and systemd
      . /etc/os-release
      OS=$NAME
      VER=$VERSION_ID
      UPSTREAM_ID=${ID_LIKE,,}
  
      # Fallback to ID_LIKE if ID was not 'ubuntu' or 'debian'
      if [ "${UPSTREAM_ID}" != "debian" ] && [ "${UPSTREAM_ID}" != "ubuntu" ]; then
         UPSTREAM_ID="$(echo ${ID_LIKE,,} | sed s/\"//g | cut -d' ' -f1)"
      fi
  elif type lsb_release >/dev/null 2>&1; then
      # linuxbase.org
      OS=$(lsb_release -si)
      VER=$(lsb_release -sr)
  elif [ -f /etc/lsb-release ]; then
      # For some versions of Debian/Ubuntu without lsb_release command
      . /etc/lsb-release
      OS=$DISTRIB_ID
      VER=$DISTRIB_RELEASE
  elif [ -f /etc/debian_version ]; then
      # Older Debian, Ubuntu, etc.
      OS=Debian
      VER=$(cat /etc/debian_version)
  elif [ -f /etc/SuSE-release ]; then
      # Older SuSE etc.
      OS=SuSE
      VER=$(cat /etc/SuSE-release)
  elif [ -f /etc/redhat-release ]; then
      # Older Red Hat, CentOS, etc.
      OS=RedHat
      VER=$(cat /etc/redhat-release)
  else
      # Fall back to uname, e.g. "Linux <version>", also works for BSD, etc.
      OS=$(uname -s)
      VER=$(uname -r)
  fi
}
# 需要通过判断系统名称和版本执行不同的命令的函数
set_code(){
  if [[ "${OS}" =~ "Ubuntu" ]] && [[ "${VER}" =~ "20.04" ]]; then
       echo $OS $VER
  elif [[ "${OS}" =~ "Ubuntu" ]] && [[ "${VER}" =~ "22.04" ]]; then
       echo $OS $VER
  elif [[ ${OS} =~ "Rocky Linux" ]] && [[ "${VER}" =~ "8" ]]; then
       echo $OS $VER
  elif [[ ${OS} =~ "Kylin Linux Advanced Server" ]] && [[ "${VER}" =~ "V10" ]]; then
       echo $OS $VER
  elif [[ ${OS} =~ "CentOS Linux" ]] && [[ "${VER}" =~ "7" ]]; then
       echo $OS $VER
  elif [[ ${OS} =~ "UnionTech OS Server" ]] && [[ "${VER}" =~ "20" ]]; then
       echo $OS $VER
  elif [[ ${OS} =~ "Alibaba Cloud Linux" ]] && [[ "${VER}" =~ "3" ]]; then
       echo $OS $VER
  fi
}

# 执行函数
OS_VER
set_code

.​ (点)、source​ 和 bash

在Shell脚本中,.​ (点)、source​ 和 bash​ 都是用来执行命令的,但它们的使用场景和行为有所不同:

  1. .​ (点):这是一个Bash内置命令,用于读取指定的文件,并执行该文件中的命令。它通常用于执行脚本文件中的命令,而不需要创建一个子shell。也就是说,使用点命令执行的脚本中的变量和函数可以保留在当前shell环境中。例如:

    . script.sh
    
  2. source​:在Bash中,source​ 是 .​ 命令的别名,它们是完全相同的,可以互换使用。在其他shell(如csh或tcsh)中,source​ 可能是一个独立的命令。例如:

    source script.sh
    
  3. bash​:这是一个用于启动一个新的Bash shell实例的命令。如果使用 bash​ 来执行一个脚本,那么脚本会在一个新的shell中运行,这意味着脚本中的变量和函数在脚本执行完毕后不会被保留在当前shell环境中。例如:

    bash script.sh
    

总结来说,.​ 和 source​ 的主要在于它们允许脚本中的变量和函数在当前shell中保持可用,而 bash​ 执行脚本则会在一个新的shell实例中进行,脚本结束后,其环境变量和函数不会影响当前shell环境。

在编写和执行Shell脚本时,选择使用哪个命令通常取决于是否需要脚本的更改(如变量赋值、函数定义等)在脚本执行后仍然对当前shell有效。如果需要,使用 .​ 或 source​;如果不需要,使用 bash​。