39

I have to get the Linux distribution name from a Python script. There is a dist method in the platform module:

import platform
platform.dist()

But under my Arch Linux it returns:

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

Why? How can I get the name?

PS. I have to check whether the distribution is Debian-based.


Update: I found here Python site, that dist() is deprecated since 2.6.

>>> platform.linux_distribution()
('', '', '')
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Max Frai
  • 57,874
  • 75
  • 193
  • 301
  • @Kimvais I mean about getting name exactly from python script without parsing any files, only standart methods. – Max Frai May 03 '10 at 07:51
  • what does `uname -a` return on Arch? platform.py is 1600 lines of trying everything they could think of to distinguish various systems; it is a huge pile of heuristics. Arch also appears to be based only on itself, no other distro: http://en.wikipedia.org/wiki/Arch_Linux – msw May 03 '10 at 08:00
  • What does `lsb_release -is` return under Arch? If `platform.dist()` gives you no usable data maybe you can call `subprocess.check_output(["lsb_release","-is"])` instead. – panzi Jul 13 '14 at 18:06
  • For googlers, here's a related question: [How do I detect the Ubuntu version?](http://stackoverflow.com/questions/19694536/how-do-i-detect-the-ubuntu-version) – blong Dec 08 '15 at 18:48
  • 4
    @Ockonal FYI linux_distribution is deprecated since 3.5 – skyking Feb 14 '17 at 09:35
  • Possible duplicate of [Python: What OS am I running on?](https://stackoverflow.com/questions/1854/python-what-os-am-i-running-on) – user7610 Sep 09 '19 at 12:01

12 Answers12

19

Here's what I found:

platform.linux_distribution

Tries to determine the name of the Linux OS distribution name.

It says platform.dist is deprecated since 2.6, you have to use platform.linux_distribution in Python 2 (but it is also deprecated in Python 3.5).

Vadim Kotov
  • 7,766
  • 8
  • 46
  • 61
nc3b
  • 14,524
  • 5
  • 49
  • 63
  • Unfortunately, `platform.linux_distribution` has been removed in python 3.8, but there's the third party package [`distro`](https://pypi.org/project/distro/). – d-k-bo Oct 15 '21 at 19:17
12

This works for me on Ubuntu:

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

I then used strace to find out what exactly the platform module is doing to find the distribution, and it is this part:

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

So, there is /etc/lsb-release containing this information, which comes from Ubuntu's Debian base-files package.

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
BjoernD
  • 4,612
  • 25
  • 32
12

The reason because of which platform.linux_distribution does not identify some distributions is the non-standardized way distributions provide version-related information on themselves.

I've written a package called distro (now used by pip) which aims to replace distro.linux_distribution. It works on many distributions which might return weird or empty tuples when using platform.

https://github.com/nir0s/distro (distro, on pypi)

It provides a much more elaborate API to retrieve distribution related information.

$ 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')

By the way, platform.linux_distribution is to be removed in Python 3.7.

nir0s
  • 1,081
  • 7
  • 17
6

To get a linux distribution name in python:

import distro
print(distro.id())

I am running Arch Linux, so this will return:

arch

For available distro id values see documenteation: https://distro.readthedocs.io/en/latest/

Ashark
  • 302
  • 3
  • 13
5

It works here. And no, Arch Linux is not Debian-based.

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

So Python does not know how to get the Arch Linux release information, and it has hardcoded looking for /etc/redhat-release and /etc/SuSE-release.

platform.dist() is an obsolete function. You should use platform.linux_distribution()

Actually, on my system it yields a different result:

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

platform.linux_distribution() looks in /etc files containing "release" or "version" as string. It also looks in the standard LSB release file. If at the end that did not work, it resorts to a _dist_try_harder function which tries to get the information from other places.

So it is up to Arch Linux to provide a standard LSB release information or to patch Python to use their "way".

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
duncan
  • 5,867
  • 3
  • 27
  • 24
2

This worked for me under Ubuntu and Manjaro:

def get_distro():
    """
    Name of your Linux distro (in lowercase).
    """
    with open("/etc/issue") as f:
        return f.read().lower().split()[0]
Jabba
  • 17,816
  • 6
  • 47
  • 43
  • 2
    not good idea , `/etc/issue` is for show welcome line on standard console and very often is modified by user/admin. Standard way to detect modern distro is parse `/etc/lsb-release` or better `/etc/os-release` – mimi.vx Mar 13 '17 at 12:05
  • for CentOS lsb-release is not available per default, so the /etc/issue works for me on more distributions as lsb-release ... – looki Aug 01 '19 at 08:30
2

Python 2 does not properly detect Arch Linux. This has been fixed in Python 3.3+, but was never back-ported to Python 2. Here are a couple of official bug reports:

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

A workaround for this issue in Python 2 is fairly simple. You just need to tell the platform module that "arch" is a supported distribution:

>>> import platform
>>> platform.linux_distribution(supported_dists=platform._supported_dists + ('arch',))
('arch', '', '')

Note that Arch Linux is a rolling release, so it does not have a version or id.

The supported_dists argument is documented here, although I don't find the documentation very clear. You don't want to overwrite _supported_dists because then your code will only work on Arch Linux. You want to append to the tuple.

In fact, if you print out the value of platform._supported_dists, you'll see that the only difference between Python 2.7.12 and Python 3.5.1 is the addition of ('arch', 'mageia'). Fun fact: you can also append 'system' for platform detection on Amazon Linux.

Adam Stewart
  • 1,700
  • 1
  • 15
  • 14
2

Here:

import sys, platform
print(sys.platform, platform.platform())
OUT [1]: linux Linux-5.4.44-1-MANJARO-x86_64-with-glibc2.2.5
Pyzard
  • 340
  • 2
  • 13
0

Two options for you:

  1. Use import platform platform.linux_distribution() # Something like ('Ubuntu', '9.10', 'karmic')

  2. Or you could just read the contents of /etc/debian_version ("squeeze/sid") or /etc/lsb-release which would give:

    DISTRIB_ID=Ubunt
    DISTRIB_RELEASE=9.10
    DISTRIB_CODENAME=karmic
    DISTRIB_DESCRIPTION="Ubuntu 9.10"
    
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
coffeetocode
  • 1,233
  • 10
  • 12
  • Unfortunately, the first option does not work on Arch Linux. I don't have access to Arch at the moment, so I can't test the second option. – Adam Stewart Nov 04 '16 at 22:16
0

If you want user readable data but still detailed, you can use platform.platform()

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

Here's a few different possible calls you can make to identify where you are

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(),
))

The outputs of this script ran on a few different systems (Linux, Windows, Solaris, MacOS) and architectures (x86, x64, Itanium, power pc, sparc) is available here: https://github.com/hpcugent/easybuild/wiki/OS_flavor_name_version

Jens Timmerman
  • 8,507
  • 1
  • 38
  • 46
0

None of the above platform answers work with latest Python versions. I've tested with Python 3.8.10. I found following methods instead.

Using platform:

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

Using distro:

>>> import distro
>>> distro.id()
'ubuntu'

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

kmchmk
  • 510
  • 9
  • 15
-1

You'll probably have to resort to:

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

or you could always augment lib/python2.6/platform.py and send in your changes.

msw
  • 41,609
  • 8
  • 82
  • 107
  • 1
    This type of comparison is dangerous because Arch Linux is not the only distribution that `platform` cannot detect. Amazon Linux also results in an empty tuple. – Adam Stewart Nov 04 '16 at 22:13