10

I'm currently writing a Python app that changes some network configuration files. The app needs to run on Ubuntu 10.04 to 13.10. The problem is, that NetworkManager is broken in different ways on different versions (though they seem to have finally fixed it in 13.04+), and this causes incompatibilities with my app.

I've figured out the problems on each version and developed workarounds for them, I'm just not sure what the best way is to detect which version of Ubuntu the user is running.

The best solution I've come up with so far is to parse the output of lsb_release -a, but this seems to be a rather fragile solution and would probably fail with Ubuntu-derived distributions such as Mint and possibly even with some of the "official" variants (Kubuntu, Xubuntu, etc.).

Is there a good way to detect the base distribution and version for a given Linux distribution so I can base the choices my app makes on that version?

Chinmay Kanchi
  • 62,729
  • 22
  • 87
  • 114
  • 2
    Maybe it would be better to detect the version of NetworkManager? – Markku K. Oct 30 '13 at 22:07
  • @MarkkuK. Perhaps, but then there is the potential of future updates breaking my app... Worth thinking about, though... – Chinmay Kanchi Oct 30 '13 at 22:13
  • There doesn't seem to be anything Python-specific, or even programming-specific, here (other than the trivial parsing bit), so you'd probably get much better answers somewhere like [Ask Ubuntu](http://askubuntu.com) than here. – abarnert Oct 30 '13 at 22:20
  • I'm asking about getting the Ubuntu distribution _via Python_. How is that not Python-specific? I suspect that this would be closed as off-topic on AskUbuntu. – Chinmay Kanchi Oct 30 '13 at 22:22
  • @ChinmayKanchi: If you knew how to get the Ubuntu version "on the command line", or "programmatically", any Python novice could immediately tell you how to get it via Python. It's that first part that's the hard part. No amount of Python expertise will be enough for someone to tell you whether `lsb_release`'s output is going to be fragile with Ubuntu-derived distributions, etc. – abarnert Oct 30 '13 at 22:25
  • 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:02

4 Answers4

13

One thing that you can do to simplify your code is to actually know one thing about how lsb_release is written. It's actually written in python.

So we could reduce most of your code to this:

>>> import lsb_release
>>> lsb_release.get_lsb_information()
{'RELEASE': '10.04', 'CODENAME': 'lucid', 'ID': 'Ubuntu', 'DESCRIPTION': 'Ubuntu 10.04.4 LTS'}

This won't necessarily help with all of the sub-ubuntu distributions, but I don't know of any builtin table to do that for you.

phoenix
  • 7,988
  • 6
  • 39
  • 45
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • This is perfect – answerSeeker Mar 07 '17 at 03:19
  • This works well. But i have python 3.8.10, and i could not find lsb_release.get_lsb_information(), rather i found lsb_release.get_distro_information() which gives me the output as {'ID': 'Ubuntu', 'DESCRIPTION': 'Ubuntu 20.04.2 LTS', 'RELEASE': '20.04', 'CODENAME': 'focal'}. – SrTan Aug 24 '21 at 09:43
  • both `lsb_release.get_os_release()` and `lsb_release.get_distro_information()` return the same information on **Python 3.8.10** – Jos Verlinde Nov 11 '21 at 20:16
8

The best options are to use the os and platform libraries.

import os
import platform

print os.name #returns os name in simple form

platform.system() #returns the base system, in your case Linux
platform.release() #returns release version

The platform library should be the more useful one.

Edit: Rob's comment on this post also highlights the more specific platform.linux_distribution() thought I would point that out here.

Dylan Lawrence
  • 1,503
  • 10
  • 32
  • 7
    Not to mention `platform.linux_distribution()` – Robᵩ Oct 30 '13 at 22:00
  • 5
    `platform.linux_distribution()` and `platform.distro()` are both deprecated since Python 3.5 and are unavailable after Python 3.7. – Daniel Jul 11 '17 at 22:35
  • 1
    I'm on Ubuntu 18.04 running Python 3.6.5rc1; `platform.linux_distribution()` works fine and returns `('Ubuntu', '18.04', 'bionic')` – PKKid Apr 04 '18 at 02:42
1

Also you can read: /etc/lsb-release or /etc/debian_version as text file

I use gentoo system, and for me:

# cat /etc/lsb-release 
DISTRIB_ID="Gentoo"
1
def getOsFullDesc():
    name = ''
    if isfile('/etc/lsb-release'):
        lines = open('/etc/lsb-release').read().split('\n')
        for line in lines:
            if line.startswith('DISTRIB_DESCRIPTION='):
                name = line.split('=')[1]
                if name[0]=='"' and name[-1]=='"':
                    return name[1:-1]
    if isfile('/suse/etc/SuSE-release'):
        return open('/suse/etc/SuSE-release').read().split('\n')[0]
    try:
        import platform
        return ' '.join(platform.dist()).strip().title()
        #return platform.platform().replace('-', ' ')
    except ImportError:
        pass
    if os.name=='posix':
        osType = os.getenv('OSTYPE')
        if osType!='':
            return osType
    ## sys.platform == 'linux2'
    return os.name
saeedgnu
  • 4,110
  • 2
  • 31
  • 48