在 Unix/Linux 平台中查找操作系统名称和版本的最佳方法

Posted

技术标签:

【中文标题】在 Unix/Linux 平台中查找操作系统名称和版本的最佳方法【英文标题】:Best way to find os name and version in Unix/Linux platform 【发布时间】:2015-01-15 06:49:04 【问题描述】:

我需要在 Unix/Linux 平台上查找操作系统名称和版本。为此,我尝试了以下操作:

    lsb_release 实用程序

    /etc/redhat-release 或特定文件

但这似乎不是最佳解决方案,因为 RHEL 7 不再支持 LSB_RELEASE。

有什么方法可以在任何 Unix 或 Linux 平台上运行吗?

【问题讨论】:

这个问题需要启发式方法,这就是为什么我给你一个 perl 的 sn-p 在 shell 中运行 lsb_release -d 可以在 ubuntu 上运行 uname 在大多数 unix 环境中,并保证在每个 LSB 兼容的 Linux 发行版上:refspecs.linuxfoundation.org/LSB_2.0.1/LSB-Core/LSB-Core/… 如何获取操作系统版本,例如。 redhat 6.5 使用 uname 吗? @Niraj - 通过阅读手册页 linux.die.net/man/1/uname 并了解它的输出(假设它在 RH6.5 中受支持)......无论哪种方式都没有(单一)便携的方式来获得它,因为它大多是无关紧要的信息。便携式程序应该探测所需的功能,而不是使用一些预先检查的发行版的白名单。 【参考方案1】:

这适用于所有 Linux 环境。

#!/bin/sh
cat /etc/*-release

在 Ubuntu 中:

$ cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.04
DISTRIB_CODENAME=lucid
DISTRIB_DESCRIPTION="Ubuntu 10.04.4 LTS"

或 12.04:

$ cat /etc/*-release

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.4 LTS"
NAME="Ubuntu"
VERSION="12.04.4 LTS, Precise Pangolin"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu precise (12.04.4 LTS)"
VERSION_ID="12.04"

在 RHEL 中:

$ cat /etc/*-release
Red Hat Enterprise Linux Server release 6.5 (Santiago)
Red Hat Enterprise Linux Server release 6.5 (Santiago)

或者使用这个脚本:

#!/bin/sh
# Detects which OS and if it is Linux then it will detect which Linux
# Distribution.

OS=`uname -s`
REV=`uname -r`
MACH=`uname -m`

GetVersionFromFile()

    VERSION=`cat $1 | tr "\n" ' ' | sed s/.*VERSION.*=\ // `


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
    KERNEL=`uname -r`
    if [ -f /etc/redhat-release ] ; then
        DIST='RedHat'
        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
        DIST=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
        REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
    elif [ -f /etc/mandrake-release ] ; then
        DIST='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
        DIST="Debian `cat /etc/debian_version`"
        REV=""

    fi
    if [ -f /etc/UnitedLinux-release ] ; then
        DIST="$DIST[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
    fi

    OSSTR="$OS $DIST $REV($PSUEDONAME $KERNEL $MACH)"

fi

echo $OSSTR

【讨论】:

是的,你是对的,但我不想从 *-release 文件中读取它。 我想要一些实用程序,比如 lsb_realease -1 : 我的archlinux上的输出是Linux 3.16.4-1-ARCH( 3.16.4-1-ARCH x86_64) 该脚本很有用,但对于 linux,它显示 ==Linux RedHat 版本(最终 2.6.32-431.el6.x86_64 x86_64)。我的 redhat 版本是 6.5,但它没有显示在输出中? 我在 RHEL6.3 上测试它显示输出为Linux RedHat 6.3(Santiago 2.6.32-279.22.1.el6.x86_64 x86_64)【参考方案2】:

以下命令对我来说很好。它为您提供操作系统名称和版本。

lsb_release -a

【讨论】:

【参考方案3】:

“lsb_release”命令提供某些 Linux 标准库和特定于发行版的信息。 所以使用下面的命令我们可以得到操作系统名称和操作系统版本。

"lsb_release -a"

【讨论】:

【参考方案4】:

此命令为您提供操作系统的描述

cat /etc/os-release

【讨论】:

如果不是Linux,或者不使用systemd怎么办?【参考方案5】:

在每个发行版中都有不同的文件,所以我写的是最常见的:

---- CentOS Linux distro
`cat /proc/version`
---- Debian Linux distro
`cat /etc/debian_version`
---- Redhat Linux distro
`cat /etc/redhat-release` 
---- Ubuntu Linux distro
`cat /etc/issue`   or   `cat /etc/lsb-release`

在最后一个 /etc/issue 中不存在,所以我尝试了第二个,它返回了正确的答案

【讨论】:

【参考方案6】:

使用perl 和Linux::Distribution,是解决老问题的最干净的解决方案:

#!/bin/sh

perl -e '
    use Linux::Distribution qw(distribution_name distribution_version);

    my $linux = Linux::Distribution->new;
    if(my $distro = $linux->distribution_name()) 
          my $version = $linux->distribution_version();
          print "you are running $distro";
          print " version $version" if $version;
          print "\n";
     else 
          print "distribution unknown\n";
    
'

【讨论】:

帖子已相应编辑。你必须安装perl的模块Linux::Distribution liblinux-distribution-perl debian & 衍生包【参考方案7】:

我自己对@kvivek's script 的看法,具有更容易机器解析的输出:

#!/bin/sh
# Outputs OS Name, Version & misc. info in a machine-readable way.
# See also NeoFetch for a more professional and elaborate bash script:
# https://github.com/dylanaraps/neofetch

SEP=","
PRINT_HEADER=false

print_help() 

    echo "`basename $0` - Outputs OS Name, Version & misc. info"
    echo "in a machine-readable way."
    echo
    echo "Usage:"
    echo "    `basename $0` [OPTIONS]"
    echo "Options:"
    echo "    -h, --help           print this help message"
    echo "    -n, --names          print a header line, naming the fields"
    echo "    -s, --separator SEP  overrides the default field-separator ('$SEP') with the supplied one"


# parse command-line args
while [ $# -gt 0 ]
do
    arg="$1"
    shift # past switch

    case "$arg" in
        -h|--help)
            print_help
            exit 0
            ;;
        -n|--names)
            PRINT_HEADER=true
            ;;
        -s|--separator)
            SEP="$1"
            shift # past value
            ;;
        *) # non-/unknown option
            echo "Unknown switch '$arg'" >&2
            print_help
            ;;
    esac
done

OS=`uname -s`
DIST="N/A"
REV=`uname -r`
MACH=`uname -m`
PSUEDONAME="N/A"

GetVersionFromFile()

    VERSION=`cat $1 | tr "\n" ' ' | sed s/.*VERSION.*=\ // `


if [ "$OS" = "SunOS" ] ; then
    DIST=Solaris
    DIST_VER=`uname -v`
    # also: cat /etc/release
elif [ "$OS" = "AIX" ] ; then
    DIST="$OS"
    DIST_VER=`oslevel -r`
elif [ "$OS" = "Linux" ] ; then
    if [ -f /etc/redhat-release ] ; then
        DIST='RedHat'
        PSUEDONAME=`sed -e 's/.*\(//' -e 's/\)//' /etc/redhat-release `
        DIST_VER=`sed -e 's/.*release\ //' -e 's/\ .*//' /etc/redhat-release `
    elif [ -f /etc/SuSE-release ] ; then
        DIST=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
        DIST_VER=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
    elif [ -f /etc/mandrake-release ] ; then
        DIST='Mandrake'
        PSUEDONAME=`sed -e 's/.*\(//' -e 's/\)//' /etc/mandrake-release`
        DIST_VER=`sed -e 's/.*release\ //' -e 's/\ .*//' /etc/mandrake-release`
    elif [ -f /etc/debian_version ] ; then
        DIST="Debian"
        DIST_VER=`cat /etc/debian_version`
    PSUEDONAME=`lsb_release -a 2> /dev/null | grep '^Codename:' | sed -e 's/.*[[:space:]]//'`
    #elif [ -f /etc/gentoo-release ] ; then
        #TODO
    #elif [ -f /etc/slackware-version ] ; then
        #TODO
    elif [ -f /etc/issue ] ; then
        # We use this indirection because /etc/issue may look like
    # "Debian GNU/Linux 10 \n \l"
        ISSUE=`cat /etc/issue`
        ISSUE=`echo -e "$ISSUE" | head -n 1 | sed -e 's/[[:space:]]\+$//'`
        DIST=`echo -e "$ISSUE" | sed -e 's/[[:space:]].*//'`
        DIST_VER=`echo -e "$ISSUE" | sed -e 's/.*[[:space:]]//'`
    fi
    if [ -f /etc/UnitedLinux-release ] ; then
        DIST="$DIST[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
    fi
    # NOTE `sed -e 's/.*(//' -e 's/).*//' /proc/version`
    #      is an option that worked ~ 2010 and earlier
fi

if $PRINT_HEADER
then
    echo "OS$SEPDistribution$SEPDistribution-Version$SEPPseudo-Name$SEPKernel-Revision$SEPMachine-Architecture"
fi
echo "$OS$SEP$DIST$SEP$DIST_VER$SEP$PSUEDONAME$SEP$REV$SEP$MACH"

注意:仅在 Debian 11 上测试

示例运行

无参数

osInfo

输出:

Linux,Debian,10.0,buster,4.19.0-5-amd64,x86_64

带有名称和自定义分隔符的标题

osInfo --names -s "\t| "

输出:

OS  | Distribution  | Distribution-Version  | Pseudo-Name   | Kernel-Revision   | Machine-Architecture
Linux   | Debian    | 10.0  | buster    | 4.19.0-5-amd64    | x86_64

过滤后的输出

osInfo | awk -e 'BEGIN  FS=",";   print $2 " " $3 " (" $4 ")" '

输出:

Debian 10.0 (buster)

【讨论】:

【参考方案8】:

我准备了以下命令来查找有关 Linux 系统的简明信息:

clear
echo "\n----------OS Information------------"
hostnamectl | grep "Static hostname:"
hostnamectl | tail -n 3
echo "\n----------Memory Information------------"
cat /proc/meminfo | grep MemTotal
echo "\n----------CPU Information------------"
echo -n "Number of core(s): "
cat /proc/cpuinfo | grep "processor" | wc -l
cat /proc/cpuinfo | grep "model name" | head -n 1
echo "\n----------Disk Information------------"
echo -n "Total Size: "
df -h --total | tail -n 1| awk 'print $2'
echo -n "Used: "
df -h --total | tail -n 1| awk 'print $3'
echo -n "Available: "
df -h --total | tail -n 1| awk 'print $4'
echo "\n-------------------------------------\n"

复制并粘贴到像 info.sh 这样的 sh 文件中,然后使用命令 sh info.sh

运行它

【讨论】:

虽然这会获取可能有用的信息,但它不能回答问题(获取操作系统名称和版本)【参考方案9】:

带引号:

cat /etc/*-release | grep "PRETTY_NAME" | sed 's/PRETTY_NAME=//g'

输出为:

"CentOS Linux 7 (Core)"

不带引号:

cat /etc/*-release | grep "PRETTY_NAME" | sed 's/PRETTY_NAME=//g' | sed 's/"//g'

输出如下:

CentOS Linux 7 (Core)

【讨论】:

以上是关于在 Unix/Linux 平台中查找操作系统名称和版本的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

在 UNIX 文件系统中查找数值的最佳方法 [重复]

浅论“跨平台”

Unix/Linux中/usr文件目录的由来

在 UNIX(Linux 首选)上学习 C++ 编程的好书? [关闭]

在windows 下编写的c语言软件可以任意移植到其他系统(例如:linux操作系统)中运行么

这些奇怪的unix/linux命令名称都是什么意思?