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

jld*_*ger 29 scripting linux

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

Mih*_*şan 37

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

  • 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
}
Run Code Online (Sandbox Code Playgroud)

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

话虽如此,您可能想要测试功能,而不是分布。我不再使用它了,因为它成为了维护负担。更容易依赖跨分发工具和解决方案。


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

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

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

source /path/to/this/script.sh
get_distribution_type
Run Code Online (Sandbox Code Playgroud)

在 bash 提示符下。


编辑:请注意,此脚本不需要 root 权限。我敦促您不要以 root 身份运行它。应该不会伤害任何东西,但没有必要。


在 CVS 日志中找到相关邮件列表帖子的链接。在解包 init 脚本意大利面时应该很有用。


wom*_*ble 27

不要试图根据发行版就你能做什么和不能做什么做出假设,因为那样做是疯狂的(另见“用户代理检测”)。相反,检测是否支持您想要执行的操作,以及您想要使用的任何命令或文​​件位置如何完成它。

例如,如果你想安装一个包,你可以通过检查 dpkg 或 rpm 的存在来检测你是在类 Debian 系统还是类 RedHat 系统上(首先检查 dpkg,因为 Debian 机器可以有他们的 rpm 命令......)。基于此来决定要做什么,而不仅仅是它是 Debian 还是 RedHat 系统。这样你就会自动支持你没有明确编程的任何衍生发行版。哦,如果你的包需要特定的依赖项,那么也测试这些依赖项并让用户知道他们缺少什么。

另一个例子是摆弄网络接口。根据是否有 /etc/network/interfaces 文件或 /etc/sysconfig/network-scripts 目录确定要做什么,然后从那里开始。

是的,这需要更多的工作,但除非您想重犯 Web 开发人员在过去十年或更长时间里犯过的所有错误,否则您将从一开始就以聪明的方式去做。


Ada*_*ins 17

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

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

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


小智 6

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

例如:

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

SUSE: /etc/SUSE-release
Run Code Online (Sandbox Code Playgroud)

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

lsb_release -a
Run Code Online (Sandbox Code Playgroud)


小智 6

python -c 'import platform ; print platform.dist()[0]'
Run Code Online (Sandbox Code Playgroud)

代码:http : //hg.python.org/cpython/file/2.7/Lib/platform.py


Nod*_*ode 5

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

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

是的,我知道这是次优的。:)