2

我在一些虚拟机上安装了 2 个版本的 python2.7.92.7.6. 2.7.6从系统包安装,而2.7.9从源安装。这台机器在 Ubuntu 14.04 上运行。

我想使用platform模块来获取有关 linux 发行版的信息。然而事实证明,在这两个版本中,我得到了不同的结果platform.linux_distribution()

Python 2.7.9 (...) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform
>>> platform.linux_distribution()
('debian', 'jessie/sid', '')


Python 2.7.6 (...) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform
>>> platform.linux_distribution()
('Ubuntu', '14.04', 'trusty')

知道为什么会这样吗?或者更一般地说,平台模块如何获取有关 linux 发行版的信息。它是基于lsb_relase或其他一些系统命令还是在某处硬编码?

4

3 回答 3

4

Ubuntu 14.04 包含两个发布文件:

# cat /etc/os-release 
NAME="Ubuntu"
VERSION="14.04.3 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.3 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

root@yeni2:/# cat /etc/debian_version 
jessie/sid

两者都被函数使用platform.linux_distribution()但是,这个函数被 Ubuntu 修补以返回 Ubuntu 操作系统名称,另见代码中的注释(右边是 Ubuntu 安装的文件,左边是 Python 2.7.10 中找到的源文件):

Python-2.7.10 # diff Lib/platform.py /mnt/ubu/\@/usr/lib/python2.7/platform.py
1c1
< #!/usr/bin/env python
---
> #! /usr/bin/python2.7
262c262
<     'UnitedLinux', 'turbolinux')
---
>     'UnitedLinux', 'turbolinux', 'Ubuntu')
290a291,294
> _distributor_id_file_re = re.compile("(?:DISTRIB_ID\s*=)\s*(.*)", re.I)
> _release_file_re = re.compile("(?:DISTRIB_RELEASE\s*=)\s*(.*)", re.I)
> _codename_file_re = re.compile("(?:DISTRIB_CODENAME\s*=)\s*(.*)", re.I)
> 
314a319,337
>     # check for the LSB /etc/lsb-release file first, needed so
>     # that the distribution doesn't get identified as Debian.
>     try:
>         with open("/etc/lsb-release", "rU") as etclsbrel:
>             for line in etclsbrel:
>                 m = _distributor_id_file_re.search(line)
>                 if m:
>                     _u_distname = m.group(1).strip()
>                 m = _release_file_re.search(line)
>                 if m:
>                     _u_version = m.group(1).strip()
>                 m = _codename_file_re.search(line)
>                 if m:
>                     _u_id = m.group(1).strip()
>             if _u_distname and _u_version:
>                 return (_u_distname, _u_version, _u_id)
>     except (EnvironmentError, UnboundLocalError):
>         pass
> 

您的 python 2.7.9 编译了源代码,不包含来自 Ubuntu 的补丁,这就是它返回内容的原因/etc/debian_version

于 2015-11-30T11:12:28.693 回答
2

查看源代码linux_distribution()

  • 它列出了所有文件/etc
  • 搜索名称匹配的文件r'(\w+)[-_](release|version)'。在我的操作系统上,它选择debian_version文件。
  • 然后它获取正则表达式 ( ) 的第一个匹配项,debian并查看它是否在支持的列表中(静态数组platform._supported_dists:)
  • 如果是,它从文件中读取信息。
  • 如果没有,它将运行_dist_try_harder(distname,version,id). 它将从/var/adm/inst-log/info,/etc/.installed/usr/lib/setup(按此顺序,解析并返回存在的第一个文件)返回版本。

因此,根据读取信息的位置,您可能会遇到不同的输出。linux_distribution()

于 2015-11-30T10:29:14.417 回答
1

platform.linux_distribution()

platform.linux_distribution (distname='', version='', id='', supported_dists=('SuSE', 'debian', 'redhat', 'mandrake', ...), full_distribution_name=1)

尝试确定 Linux OS 分发名称的名称。

Supported_dists 可用于定义要查找的 Linux 发行版集。它默认为由发行文件名标识的当前支持的 Linux 发行版列表。

如果 full_distribution_name 为 true(默认),则返回从操作系统读取的完整分布。否则使用从supported_dists 中获取的短名称。

返回一个元组 (distname,version,id),默认为作为参数给出的 args。id 是版本号后面括号中的项目。它通常是版本代号。

https://docs.python.org/2/library/platform.html?highlight=platform.linux_distribution#platform.linux_distribution

根据您的2.7.9结果,该命令无法full_distribution_name从操作系统确定(因为它显示为空白),所以它supported_dists改为使用。

于 2015-11-30T10:29:06.293 回答