如何可靠地获取操作系统的名称?

如何可靠地获取操作系统的名称?

假设我登录到远程系统,我如何知道它正在运行什么?在大多数现代 Linux(Linux?)上,您有以下lsb_release命令:

$ lsb_release -ic    
Distributor ID: LinuxMint
Codename:       debian

据我所知,它提供了与 相同的信息/etc/lsb-release。如果该文件不存在怎么办?我似乎记得该lsb_release命令相对较新,那么如果我必须获取旧系统的操作系统怎么办?

无论如何,lsb代表Linux Standard Base所以我假设它不能在非 Linux Unices 上工作。据我所知,无法从中获取此信息,uname那么我如何在不使用 的系统上获取此信息lsb_release

答案1

lsb_release -a可能是您查找此信息并能够以一致的方式找到此信息的最佳选择。

LSB 的历史

该命令中的lsb代表项目Linux 标准库这是一个由Linux基金会提供在各种 Linux 发行版上执行基本操作的通用方法。

该项目是自愿性的,供应商可以作为用户参与该项目,也可以作为不同模块的各种规范的促进者参与,这些规范有助于推动不同 Linux 发行版内的标准化。

摘自宪章

LSB 工作组的核心目标就是解决这两个问题。我们与主要发行版供应商协商后发布了一个标准,描述发行版必须支持的最小 API 集。我们还提供测试和工具来衡量对标准的支持,并使应用程序开发人员能够瞄准通用集。最后,通过我们的测试工作,我们力求防止分布之间出现不必要的分歧。

与 LSB 相关的有用链接

批评

LSB 存在许多问题,这给 Debian 等发行版带来了问题。强制使用 RPM 就是其中之一。请参阅维基百科文章了解更多有关此事的信息

诺维尔

如果您进行搜索,您可能会发现一个看起来相当过时的页面,标题为:检测底层 Linux 发行版来自诺维尔。这是我见过的少数几个有实际列表的地方之一,其中显示了几个主要发行版以及如何检测您正在使用的底层发行版。

摘抄

Novell SUSE         /etc/SUSE-release
Red Hat             /etc/redhat-release, /etc/redhat_version
Fedora              /etc/fedora-release
Slackware           /etc/slackware-release, /etc/slackware-version
Debian              /etc/debian_release, /etc/debian_version,
Mandrake            /etc/mandrake-release
Yellow dog          /etc/yellowdog-release
Sun JDS             /etc/sun-release
Solaris/Sparc       /etc/release
Gentoo              /etc/gentoo-release
UnitedLinux         /etc/UnitedLinux-release
ubuntu              /etc/lsb-release

uname该同一页面还包括一​​个方便的脚本,该脚本尝试仅使用普通命令以及上述文件之一的存在来对上述内容进行编码。

笔记:此列表已过时,但您可以轻松地从列表中删除过时的发行版(例如 Mandrake)并用替代品替换它们。如果您尝试支持大量 Solaris 和 Linux 变体,这种类型的脚本可能是一种方法。

Linux黑手党

更多搜索将出现 Linuxmafia.com 上维护的以下页面,标题为: 各种 Linux(和其他 Unix)发行版的 /etc/release 等效项。这可能是迄今为止我见过的最详尽的列表。您可以使用 case/switch 语句来编写此列表,并将其包含在您的软件分发中。

事实上,该页面底部有一个脚本可以做到这一点。因此,您可以作为软件发行版的第三方下载并使用该脚本。

脚本

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

笔记:该脚本应该看起来很熟悉,它是 Novell 脚本的最新版本!

腿部空间脚本

我见过的另一种方法是滚动您自己的脚本,类似于上面的 Novell 方法,但使用 LSB。这篇文章的标题是:确定 Linux(或 UNIX)发行版名称的通用方法,展示了一种这样的方法。

# 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

这段代码可以包含到系统/etc/bashrc或某些此类文件中,然后设置环境变量$DISTRO

海湾合作委员会

不管你相信与否,另一种方法是使用gcc.如果您查询该命令,gcc --version您将获得构建 gcc 的发行版,该发行版始终与其运行的系统相同。

软呢帽 14

$ gcc --version
gcc (GCC) 4.5.1 20100924 (Red Hat 4.5.1-4)
Copyright (C) 2010 Free Software Foundation, Inc.

CentOS 5.x

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

CentOS 6.x

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

乌班图12.04

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

TL;博士;

那么我应该使用哪一个呢?我倾向于选择lsb_release -a我经常使用的任何 Linux 发行版(RedHat、Debian、Ubuntu 等)。对于您支持不提供的系统的情况,lsb_release我将推出自己的系统作为我提供的软件分发的一部分,类似于上述脚本之一。

更新#1:SuSE 的跟进

在下面的评论中与 @Nils 交谈时确定,无论出于何种原因,SLES11 似乎放弃了默认安装的 LSB。这只是一个可选安装,这似乎与提供此类关键功能的软件包相反。

因此,我借此机会联系了 OpenSuSE 项目的人员来了解原因。

电子邮件摘录

Hi Rob,

I hope you don't mind me contacting you directly but I found your info here: 
https://en.opensuse.org/User:Rjschwei. I participate on one of the StackExchange 
sites, Unix & Linux and a question recently came up regarding the best option 
for determining the underlying OS.

http://unix.stackexchange.com/questions/92199/how-can-i-reliably-get-the-operating-systems-name/92218?noredirect=1#comment140840_92218

In my answer I suggested using lsb_release, but one of the other users mentioned 
that this command wasn't installed as part of SLES11 which kind of surprised me. 
Anyway we were looking for some way to confirm whether this was intentionally 
dropped from SLES or it was accidental.

Would you know how we could go about confirming this one way or another?

Thanks for reading this, appreciate any help and/or guidance on this.

-Sam Mingolelli
http://unix.stackexchange.com/users/7453/slm

这是罗布的回应

Hi,

On 10/01/2013 09:31 AM, Sam Mingo wrote:
- show quoted text -

lsb_release was not dropped in SLES 11. SLES 11 is LSB certified. However, it 
is not installed by default, which is consistent with pretty much every other
distribution. The lsb_release command is part of the lsb-release package.

At present almost every distribution has an entry in /etc such as 
/etc/SuSE-release for SLES and openSUSE. Since this is difficult for ISVs and 
others there is a standardization effort going on driven by the convergence to 
systemd. The standard location for distribution information in the future will 
be /etc/os-release, although Ubuntu will probably do something different.

HTH,    
Robert

--  Robert Schweikert                           MAY THE SOURCE BE WITH YOU    
SUSE-IBM Software Integration Center                   LINUX    
Tech Lead    
Public Cloud Architect 

答案2

由于您可能无法facter在远程服务器上安装,因此您可以模仿它的操作来查找操作系统名称。operatingsystem可以找到该事实的 Ruby 代码在pastebin上。基本上,它会查看不同的*-release文件和其他文件来确定操作系统名称。

它查看的一些文件:

/etc/debian_version
/etc/gentoo-release
/etc/fedora-release
/etc/mandriva-release
/etc/mandrake-release
/etc/meego-release
/etc/arch-release
/etc/oracle-release
/etc/enterprise-release
/etc/ovs-release
/etc/vmware-release
/etc/redhat-release
/etc/SuSE-release
/etc/bluewhite64-version
/etc/slamd64-version
/etc/slackware-version
/etc/alpine-release
/etc/system-release
/etc/centos-release

如果您在此列表中发现重复项,我很抱歉,我用 快速生成了它grep。将其移植到 POSIX shell 脚本应该相当容易(尽管有点乏味)。

答案3

如果你已经python安装了(无论Python 3还是Python 2),你可以找到发行版名称无需重新发明轮子:

python -c "import platform;print(platform.linux_distribution()[0])"

答案4

您无法通过所有发行版的单个命令可靠地获取发行版名称。有些可以通过 /etc/*-release 获得,其他可以通过“lsb-release”命令获得。

相关内容