检查Linux发行版名称

42

我需要从一个Python脚本中获取Linux发行版的名称。在platform模块中有一个dist方法:

import platform
platform.dist()

但是在我的 Arch Linux 上,它返回:

>>> platform.dist()
('', '', '')

为什么?我该如何获取名称?

附注:我必须检查发行版是否基于Debian。


更新:我在这里发现Python网站,dist()自2.6版起已弃用。

>>> platform.linux_distribution()
('', '', '')

@Kimvais 我的意思是在不解析任何文件的情况下,仅使用标准方法从Python脚本中精确获取名称。 - Max Frai
uname -a 在 Arch 上返回什么?platform.py 是 1600 行代码,尝试了所有可能的方法来区分各种系统;它是一个庞大的启发式堆积。Arch 似乎也只基于自身,没有其他发行版:http://en.wikipedia.org/wiki/Arch_Linux - msw
lsb_release -is 在 Arch 下返回什么?如果 platform.dist() 没有给你可用的数据,也许你可以调用 subprocess.check_output(["lsb_release","-is"]) - panzi
对于谷歌员工,这里有一个相关的问题:如何检测Ubuntu版本? - blong
4
FYI linux_distribution自3.5版本开始已被弃用。 - skyking
可能是Python:我正在运行什么操作系统?的重复问题。 - user7610
15个回答

20

这里是我找到的:

platform.linux_distribution

该段内容尝试确定Linux操作系统发行版名称,它指出自2.6版本起platform.dist已被弃用,在Python 2中必须使用platform.linux_distribution(但在Python 3.5中也被弃用)。


1
不幸的是,在Python 3.8中,platform.linux_distribution已被删除,但有第三方包distro可供使用。 - d-k-bo

16
platform.linux_distribution无法识别某些发行版的原因是,这些发行版提供与版本相关的信息的方式不太规范。我编写了一个名为distro的软件包(现在被pip使用),旨在替换distro.linux_distribution。它适用于许多发行版,在使用platform时可能会返回奇怪或空的元组。这里是https://github.com/nir0s/distrodistro,在pypi上)。它提供了更加详细的API来检索与发行版相关的信息。
$ python
Python 2.7.12 (default, Nov  7 2016, 11:55:55) 
[GCC 6.2.1 20160830] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import distro
>>> distro.linux_distribution()
(u'Antergos Linux', '', u'ARCHCODE')

顺便提一下,platform.linux_distribution将在Python 3.7中被移除。


12

这对我在Ubuntu上有效:

('Ubuntu', '10.04', 'lucid')

我随后使用strace来查找平台模块查找发行版的确切操作,具体是这一部分:

open("/etc/lsb-release", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=102, ...}) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=102, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76b1000
read(3, "DISTRIB_ID=Ubuntu\nDISTRIB_RELEAS"..., 8192) = 102
read(3, "", 4096)                       = 0
read(3, "", 8192)                       = 0
close(3)                                = 0

所以,有一个/etc/lsb-release文件包含这些信息,该文件来自Ubuntu的Debian base-files软件包。


请注意,有时文件是 /etc/os-release - panzi

6

在Python中获取Linux发行版名称:

import distro
print(distro.id())

我在运行Arch Linux,因此这将返回:

arch

可用的发行版 ID 值请参阅文档:https://distro.readthedocs.io/en/latest/


5

它在这里运行良好。不,Arch Linux 不是基于 Debian 的。

>>> import platform
>>> platform.dist()
('SuSE', '11.2', 'x86_64')

因此,Python不知道如何获取Arch Linux的发行信息,并且它已经硬编码查找/etc/redhat-release和/etc/SuSE-release。

platform.dist()是一个过时的函数。你应该使用platform.linux_distribution()

实际上,在我的系统上,它产生了不同的结果:

>>> platform.linux_distribution()
('openSUSE ', '11.2', 'x86_64')

platform.linux_distribution()会查找包含字符串“release”或“version”的/etc文件。它还会查找标准的LSB发行版文件。如果最终无法获得信息,它将使用_dist_try_harder函数尝试从其他地方获取信息。

因此,Arch Linux需要提供标准的LSB发行版信息或修补Python以使用他们的“方法”。


3
现在有一个可以使用的platform.freedesktop_os_release()方法,据我所知,它支持每个Linux发行版,包括Arch。
>>> import platform
>>> platform.freedesktop_os_release()
{'NAME': 'Arch Linux', 'ID': 'arch', 'PRETTY_NAME': 'Arch Linux', 'BUILD_ID': 'rolling', 'ANSI_COLOR': '38;2;23;147;209', 'HOME_URL': 'https://archlinux.org/', 'DOCUMENTATION_URL': 'https://wiki.archlinux.org/', 'SUPPORT_URL': 'https://bbs.archlinux.org/', 'BUG_REPORT_URL': 'https://bugs.archlinux.org/', 'LOGO': 'archlinux-logo'}

为了检查分发版本,您应该使用名称或ID输入。在任何Linux系统上都可以更改值,但这些值默认是可用的。


1
请注意,此功能仅适用于Python 3.10及更高版本(https://docs.python.org/3/library/platform.html#platform.freedesktop_os_release)。 - AngryUbuntuNerd

3

Here:

import sys, platform
print(sys.platform, platform.platform())

OUT [1]: linux Linux-5.4.44-1-MANJARO-x86_64-with-glibc2.2.5

2

这对我在Ubuntu和Manjaro下都有效:

def get_distro():
    """
    Name of your Linux distro (in lowercase).
    """
    with open("/etc/issue") as f:
        return f.read().lower().split()[0]

3
不是好主意,/etc/issue 文件用于在标准控制台上显示欢迎信息,并经常由用户/管理员进行修改。检测现代发行版的标准方法是解析 /etc/lsb-release 或更好的 /etc/os-release 文件。 - mimi.vx
对于CentOS,lsb-release默认不可用,因此/etc/issue在更多发行版上适用于我... - looki

2
Python 2 无法正确检测 Arch Linux。这个问题已经在 Python 3.3+ 中得到修复,但从未被移植到 Python 2。以下是几个官方的错误报告:

https://bugs.python.org/issue20454
https://bugs.python.org/issue11678

Python 2 中解决此问题的方法相当简单。您只需要告诉平台模块,“arch”是受支持的分发版本:
>>> import platform
>>> platform.linux_distribution(supported_dists=platform._supported_dists + ('arch',))
('arch', '', '')

请注意,Arch Linux是一个滚动更新的发行版,因此它没有版本或ID。
`supported_dists`参数在这里有文档记录,尽管我认为文档不太清楚。您不想覆盖`_supported_dists`,因为那样你的代码将仅适用于Arch Linux。您需要将其附加到元组中。
实际上,如果您打印出`platform._supported_dists`的值,您会发现Python 2.7.12和Python 3.5.1之间唯一的区别是添加了`('arch', 'mageia')`。有趣的事实是:您还可以附加`'system'`以进行Amazon Linux上的平台检测。

1

以上 平台 答案都不适用于最新的 Python 版本。我已经测试过 Python 3.8.10。我找到了以下方法。

使用平台:

>>> import platform
>>> platform.version()
'#29~20.04.1-Ubuntu SMP Wed Aug 11 15:58:17 UTC 2021'

使用发行版:
>>> import distro
>>> distro.id()
'ubuntu'

参考: https://docs.python.org/3/library/platform.html#platform.linux_distribution


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接