如何找出正在运行的Linux版本?


29

有时,您的脚本需要在不同的Linux上表现不同。如何确定脚本运行在哪个Linux版本上?


1
按版本,您是指内核版本吗?什么分布?发行版?
克里斯·厄普彻奇

2
我确定jldugger希望找出系统正在运行的发行系列。除非脚本依赖某些/ sys或/ proc东西,否则脚本不太可能受内核版本的影响-即使那样,通常也可以根据发行版而不是内核进行假设。
MihaiLimbăşan,2009年

Answers:


27

不要尝试根据发行版来确定您可以做什么和不能做什么,因为这是疯狂的原因(另请参见“用户代理检测”)。相反,请检测是否支持您要执行的操作,以及如何通过要使用的命令或文件位置来完成操作。

例如,如果要安装软件包,则可以通过检查dpkg或rpm是否存在来检测您是在Debian还是RedHat上(首先检查dpkg,因为Debian机器可以安装dpkg)。他们上的rpm命令...)。在此基础上,决定要做什么,而不仅仅是决定是Debian还是RedHat系统。这样,您将自动支持未明确编程的任何派生发行版。哦,如果您的程序包需要特定的依赖项,那么也请测试这些依赖项,并让用户知道它们的缺失。

另一个示例是摆弄网络接口。根据是否存在/ etc / network / interfaces文件或/ etc / sysconfig / network-scripts目录来确定要执行的操作,然后从那里开始。

是的,这是更多的工作,但是除非您要重现Web开发人员在过去十年或更长时间里犯下的所有错误,否则从一开始就将明智地做到这一点。


1
(扩展此答案)在某些情况下,最好使用特征检测,但是请确保不要尝试从所检测的特征中猜测分布!不要误解答案,并根据/ etc中的文件确定平台是否为RedHat。如果确实需要分发名称,请检查lsb_release(或/ etc / redhat-release,依此类推)。
尼古拉斯·威尔逊

36

没有交叉分配的方式。然而:

  • Redhat和朋友:测试/etc/redhat-release,检查内容
  • Debian:测试/etc/debian_version,检查内容
  • Mandriva和朋友:测试/etc/version,检查内容
  • Slackware:测试/etc/slackware-version,检查内容

等等,一般来说,请检查/etc/*-release/etc/*-version


编辑:发现我的旧的(1年以上)bash脚本遍布我,这些年来我肯定已经凑齐了(它有一个令人印象深刻的CVS日志可以追溯到6年。)它可能无法正常工作,我可以不必费心查找要测试的已安装发行版,但这应该为您提供了一个很好的起点。它在CentOS,Fedora和Gentoo上运行良好。gyaresu在Debian Lenny上成功测试了它。

#!/bin/bash

get_distribution_type()
{
    local dtype
    # Assume unknown
    dtype="unknown"

    # First test against Fedora / RHEL / CentOS / generic Redhat derivative
    if [ -r /etc/rc.d/init.d/functions ]; then
        source /etc/rc.d/init.d/functions
        [ zz`type -t passed 2>/dev/null` == "zzfunction" ] && dtype="redhat"

    # Then test against SUSE (must be after Redhat,
    # I've seen rc.status on Ubuntu I think? TODO: Recheck that)
    elif [ -r /etc/rc.status ]; then
        source /etc/rc.status
        [ zz`type -t rc_reset 2>/dev/null` == "zzfunction" ] && dtype="suse"

    # Then test against Debian, Ubuntu and friends
    elif [ -r /lib/lsb/init-functions ]; then
        source /lib/lsb/init-functions
        [ zz`type -t log_begin_msg 2>/dev/null` == "zzfunction" ] && dtype="debian"

    # Then test against Gentoo
    elif [ -r /etc/init.d/functions.sh ]; then
        source /etc/init.d/functions.sh
        [ zz`type -t ebegin 2>/dev/null` == "zzfunction" ] && dtype="gentoo"

    # For Slackware we currently just test if /etc/slackware-version exists
    # and isn't empty (TODO: Find a better way :)
    elif [ -s /etc/slackware-version ]; then
        dtype="slackware"
    fi
    echo $dtype
}

请注意,这可能只能在Bash中正常工作。您可以将其重写为其他shell。

话虽如此,您可能需要测试功能而不是发行版。我不再仅仅因为它已成为维护负担而使用它。依靠交叉分发工具和解决方案更加容易。


从概念上讲,它的作用是:

  • 提取一个已知的“公共初始化脚本功能”类型的文件。这些是特定于发行版的。如果不存在,请跳至下一个分发检查。
  • 检查该核心脚本中是否存在特定的,已知的,经常使用的且不太可能重命名的功能。我们使用type内置的Bash来做到这一点。type -t返回function该符号是否为函数。我们zz把输出放在前面,type -t 2>/dev/null因为如果未定义名称,则输出字符串将为空,并且会收到有关==操作员缺少左手的语法错误。如果我们刚刚检查的名称不是函数,请跳至下一个分发检查,否则我们找到了分发类型。
  • 最后,回显分配类型,以便可以在esac块中轻松使用函数输出。

编辑,以防您尝试将其作为纯脚本运行:该脚本应该从其他脚本中获取或包含。如果按原样运行,它不会自行输出任何内容。要对其进行测试,请获取其源代码,然后调用该函数,例如:

source /path/to/this/script.sh
get_distribution_type

在bash提示下。


编辑:请注意,此脚本不需要root特权。我敦促您不要以root用户身份运行它。不应伤害任何事物,但没有必要。


在CVS日志中找到相关邮件列表帖子的链接。在展开初始化脚本意大利面条时应该很有用。


我没有看过为什么,但是它在Debian Lenny(5.0)上返回提示。
加雷斯

gyaresu,您是否真的调用过get_distribution_type函数?我已编辑帖子以澄清(请参阅底部。)
MihaiLimbăşan,2009年

@gyaresu:如果以上都不是问题,可以请您尝试将Debian部分中的log_begin_msg替换为log_warning_msg并重试吗?可能弄错了功能名称。在任何情况下,如果该功能不是正常的,它仍然应该返回“未知”。
MihaiLimbăşan,2009年

@Mihai Doh!抱歉。没有正确阅读脚本。早了,没有咖啡。对不起 gyaresu @ debian:〜/ bin $源server_version.sh gyaresu @ debian:〜/ bin $ get_distribution_type debian
Gareth

@gyaresu:谢谢!很好,应该可以帮助jldugger知道它也可以在Debian上使用:)
MihaiLimbăşan,2009年

17

您可以通过运行找到内核版本uname -a,查找发行版版本取决于发行版。

在Ubuntu和其他一些操作系统上,您可以运行lsb_release -a或阅读/ etc / lsb_release

Debian将版本存储在/ etc / debian_version中


lsb_release +1(如果安装了正确的软件包,也可以在Red Hat衍生产品上使用)
Josh Kelley 2009年

仅用于描述“ lsb_release -ds”。
flickerfly 2014年

6

大多数发行版都有确定特定发行版的独特方法。

例如:

Redhat (And derivatives): /etc/redhat-release

SUSE: /etc/SUSE-release

那里有一个称为Linux Standard BaseLSB的标准。它定义应该存在一个名为/ etc / lsb-release的文件或一个名为lsb_release的程序,该程序将回显有关Linux发行版的信息。

lsb_release -a

当然,lsb_release在CentOS 6上并不存在。–
Justin


5

除了其他答案:如果您只想解析一个文件,大多数发行版都通过/ etc / issue个性化tty登录,例如:

欢迎使用SUSE Linux Enterprise Server 10 SP2(i586)-内核\ r(\ l)。

是的,我知道它不是最理想的。:)


它可能不是最优的,但它位于同一位置。
布拉德·吉尔伯特

4

Facter是用于这种发现的便捷工具,尽管它可能使用了上面详述的某些方法,并且需要Ruby。


2

您需要做的就是键入uname -a您喜欢的shell。这将打印出内核名称和版本。


2

我发现cat /etc/*release*几乎总是可行。


2

我同意马克,亚当和米海(由于声望不足而无法投票)。基于LSB及其相对FHS的解决方案将适用于大多数发行版,并且将来可能会继续使用。LSB和FHS是您的朋友。


2

您也可以通过以下方式获取版本

cat /proc/version

o / p:

Linux版本2.6.17-13mdv(rtp@octopus.mandriva.com)(gcc版本4.1.2 20070302(预发行)(4.1​​.2-1mdv2007.1))#1 SMP Fri Mar 23 19:03:31 UTC 2007


1

linux的版本是一个难题。如果我们狭义地看一下,我们可以使用“ uname -r” 获得内核版本。发行版本大多是反讽的。有些发行版更好(企业发行版,如Redhat Enterprise Linux)。其他发行版(例如Gentoo)基本上都是移动目标,根本没有明智的版本。如果您需要根据版本进行操作,请查看与您相关的主要组件:

Component       Version command
glibc           /lib/libc.so.6
gcc             gcc --version
X               xdpyinfo
libX11          pkg-config --modversion x11
gtk+            pkg-config --modversion gtk+-2.0
qt-4            pkg-config --modversion QtCore

   etc...


-1

FusionInventory是一种跨平台的轻量级清单工具,可以在许多Linux发行版上以及在BSD,Windows,MacOS X和其他unices上获得此信息。

如果可用,它们将使用lsb_release(如上几次提到),但是如果没有,它们将具有非常有用的文件列表和正则表达式来检查发行版名称和版本:https : //github.com/fusinv/fusioninventory-agent/ blob / 2.2.x / lib / FusionInventory / Agent / Task / Inventory / Input / Linux / Distro / NonLSB.pm#L16

我建议使用FusionInventory本身来获取此信息,而不是使用此逻辑重新实现自己的脚本,因为它们的社区将保持该功能的最新状态。您可以单独使用代理(它会输出易于解析的XML / JSON文件),也可以根据需要将其与更广泛的解决方案结合使用,以管理GLPIRudder等网络中的计算机。


如果它不具有Perl模块的外部依赖性,这将是一个很好的解决方案
Will Sheppard
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.