Проверьте название дистрибутива Linux

Мне нужно получить имя дистрибутива Linux из скрипта Python. В модуле платформы есть метод dist:

import platform
platform.dist()

Но под моим Arch Linux он возвращается:

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

Почему? Как я могу получить имя?

PS. Я должен проверить, основан ли дистрибутив на Debian.


Обновление: я нашел здесь сайт Python, этот dist () устарел, так как 2.6.

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

person Max Frai    schedule 03.05.2010    source источник
comment
@Kimvais Я имею в виду получение имени именно из скрипта python без разбора файлов, только стандартные методы.   -  person Max Frai    schedule 03.05.2010
comment
что uname -a возвращает на Arch? platform.py - это 1600 строк попытки всего, что они могли придумать, чтобы различать различные системы; это огромная куча эвристик. Похоже, что Arch основан только на себе, а не на другом дистрибутиве: en.wikipedia.org/wiki/Arch_Linux < / а>   -  person msw    schedule 03.05.2010
comment
Что lsb_release -is возвращается в Arch? Если platform.dist() не дает вам пригодных для использования данных, возможно, вы можете вместо этого вызвать subprocess.check_output(["lsb_release","-is"]).   -  person panzi    schedule 13.07.2014
comment
@Ockonal FYI linux_distribution устарел с версии 3.5   -  person skyking    schedule 14.02.2017


Ответы (11)


Это работает для меня в 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, содержащая эту информацию, которая поступает из пакета базовых файлов Debian Ubuntu.

person BjoernD    schedule 03.05.2010
comment
Обратите внимание, что иногда это /etc/os-release. - person panzi; 13.07.2014

Вот что я нашел:

platform.linux_distribution

Пытается определить название дистрибутива ОС Linux.

Он говорит, что platform.dist устарел, начиная с версии 2.6, вы должны использовать platform.linux_distribution в Python 2 (но он также устарел в Python 3.5).

person nc3b    schedule 03.05.2010

Причина, по которой platform.linux_distribution не идентифицирует некоторые дистрибутивы, заключается в нестандартизированном способе предоставления дистрибутивами информации о самих версиях.

Я написал пакет под названием distro (сейчас используется pip), который призван заменить distro.linux_distribution. Он работает во многих дистрибутивах, которые могут возвращать странные или пустые кортежи при использовании platform.

https://github.com/nir0s/distro (distro, на 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.

person nir0s    schedule 01.04.2017

Здесь работает. И нет, 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 () просматривает файлы / etc, содержащие «выпуск» или «версию» в виде строки. Он также просматривается в стандартном файле выпуска LSB. Если в конце это не сработало, он прибегает к функции _dist_try_harder, которая пытается получить информацию из других мест.

Таким образом, Arch Linux должен предоставить стандартную информацию о выпуске LSB или исправить Python, чтобы использовать их «путь».

person duncan    schedule 03.05.2010

Это сработало для меня под Ubuntu и Manjaro:

def get_distro():
    """
    Name of your Linux distro (in lowercase).
    """
    with open("/etc/issue") as f:
        return f.read().lower().split()[0]
person Jabba    schedule 30.05.2015
comment
не очень хорошая идея, /etc/issue используется для отображения приветственной строки на стандартной консоли и очень часто изменяется пользователем / администратором. Стандартный способ определить современный дистрибутив - это синтаксический анализ /etc/lsb-release или лучше /etc/os-release - person mimi.vx; 13.03.2017
comment
для CentOS lsb-release недоступен по умолчанию, поэтому / etc / issue работает для меня в других дистрибутивах, таких как lsb-release ... - person looki; 01.08.2019

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 - это скользящий выпуск, поэтому у него нет версии или идентификатора.

Аргумент supported_dists задокументирован здесь, хотя я не найти документацию очень понятной. Вы не хотите перезаписывать _supported_dists, потому что тогда ваш код будет работать только в Arch Linux. Вы хотите добавить в кортеж.

Фактически, если вы распечатаете значение platform._supported_dists, вы увидите, что единственная разница между Python 2.7.12 и Python 3.5.1 заключается в добавлении ('arch', 'mageia'). Интересный факт: вы также можете добавить 'system' для определения платформы в Amazon Linux.

person Adam Stewart    schedule 04.11.2016

Чтобы получить имя дистрибутива Linux в Python:

import distro
print(distro.id())

Я использую Arch Linux, поэтому вернусь:

arch

Доступные значения идентификаторов дистрибутивов см. В документации: https://distro.readthedocs.io/en/latest/ < / а>

person Ashark    schedule 09.07.2020

Здесь:

import sys, platform
print(sys.platform, platform.platform())
OUT [1]: linux Linux-5.4.44-1-MANJARO-x86_64-with-glibc2.2.5
person Pyzard    schedule 15.07.2020

Для вас два варианта:

  1. Используйте платформу импорта platform.linux_distribution () # Что-то вроде ('Ubuntu', '9.10', 'karmic')

  2. Или вы можете просто прочитать содержимое / etc / debian_version ("squeeze / sid") или / etc / lsb-release, что даст:

    DISTRIB_ID=Ubunt
    DISTRIB_RELEASE=9.10
    DISTRIB_CODENAME=karmic
    DISTRIB_DESCRIPTION="Ubuntu 9.10"
    
person coffeetocode    schedule 03.05.2010
comment
К сожалению, первый вариант не работает в Arch Linux. На данный момент у меня нет доступа к Arch, поэтому я не могу протестировать второй вариант. - person Adam Stewart; 05.11.2016

Если вам нужны данные, читаемые пользователем, но все же подробные, вы можете использовать platform.platform ()

>>> import platform
>>> platform.platform()
'Linux-3.3.0-8.fc16.x86_64-x86_64-with-fedora-16-Verne'

Вот несколько разных возможных звонков, которые вы можете сделать, чтобы узнать, где вы находитесь.

import platform
import sys

def linux_distribution():
  try:
    return platform.linux_distribution()
  except:
    return "N/A"

print("""Python version: %s
dist: %s
linux_distribution: %s
system: %s
machine: %s
platform: %s
uname: %s
version: %s
mac_ver: %s
""" % (
sys.version.split('\n'),
str(platform.dist()),
linux_distribution(),
platform.system(),
platform.machine(),
platform.platform(),
platform.uname(),
platform.version(),
platform.mac_ver(),
))

Результаты этого скрипта выполнялись в нескольких разных системах (Linux, Windows, Solaris, MacOS) и архитектурах (x86, x64, Itanium, power pc, sparc) доступны здесь: https://github.com/hpcugent/easybuild/wiki/OS_flavor_name_version

person Jens Timmerman    schedule 09.01.2019
comment
platform.linux_distribution() устарел с версии 3.5 - person code_dredd; 23.11.2019
comment
@code_dredd да, вам, вероятно, не следует использовать его или полагаться на его присутствие, поскольку он уже находится в блоке try / except, здесь этот код не сломается после его удаления;) - person Jens Timmerman; 29.11.2019

Вероятно, вам придется прибегнуть к:

if platform.linux_distribution() == ('', '', ''):
    # do something specific to look for Arch

или вы всегда можете дополнить lib / python2.6 / platform.py и отправить свои изменения.

person msw    schedule 03.05.2010
comment
Этот тип сравнения опасен, потому что Arch Linux - не единственный дистрибутив, который platform не может обнаружить. Amazon Linux также приводит к пустому кортежу. - person Adam Stewart; 05.11.2016