6

I'm developing a script that needs the package managers of a System. I've identified Fedora, Gentoo, and Arch Linux using the os.uname() function.

However, the (open)SUSE uname results is the same as other Linux Distros. I found the uname results of many distros on Wikipedia.

Is there any smart way to identify (open)SUSE with Python?

Ben
  • 51,770
  • 36
  • 127
  • 149
ant0nisk
  • 581
  • 1
  • 4
  • 17
  • 4
    this is dangerous to use in the first place. what is your _actual_ problem? can't you just check for specific capabilities you need? –  Jun 17 '12 at 19:10
  • I need to know if the OS is (Open)SUSE so as to use the correct package installer (zypper). If it is DEBIAN (For Example), I will use apt-get... That's why I need this.... – ant0nisk Jun 17 '12 at 19:13
  • CristopheD, I think that your answer covers what I need! Thank you!!! – ant0nisk Jun 17 '12 at 19:13
  • 4
    I think what @hop means is, wouldn't it be better to check which package manager is available, rather than inferring it from the host operating system? – chepner Jun 17 '12 at 19:51
  • 2
    @ChristopheD you should be very careful with /proc/version in virtualized environments. First, it's gcc version there. Second, you may see the host's kernel version that may be from a different distribution. – unbeli Jun 17 '12 at 20:19
  • Another option is to read from `/etc/issue`. It doesn't necessarily follow a standard format, though. `lsb_release` is a better choice. – Joe Kington Jun 17 '12 at 21:29
  • @unbeli: thanks for the comment, did not realize /proc/version could break virtualization boundaries... – ChristopheD Jun 18 '12 at 08:02

4 Answers4

8

From the comments at the top:

  • I need to know if the OS is (Open)SUSE so as to use the correct package installer (zypper). If it is DEBIAN (For Example), I will use apt-get...

I suggest you directly solve the actual problem. Instead of identifying the OS, identify the package manager available.

import os

if os.path.exists('/usr/bin/zypper'):
    ... # do the SUSE case
elif os.path.exists('/usr/bin/apt-get'):
    ... # do the Debian/Ubuntu case
elif os.path.exists('/usr/bin/yum'):
    ... # do the Red Hat case
else:
    raise OSError, "cannot find a usable package manager"

EDIT: Although the code here shows detecting the package manager program, it might be better to detect the main package registry itself. For example, on Debian/Ubuntu systems that use dpkg, there will be a directory /var/lib/dpkg holding the package database; that is a sure sign that dpkg or apt-get are appropriate. I don't know what the equivalent directories are for SUSE and Red Hat and so on, but if you are supporting those you can find out.

apt-get has been ported to Red Hat systems, and via a program called alien you can get rpm on Debian systems, and so on. Detecting the package database itself is the most foolproof way of figuring out what package system is in use.

If you detect the package manager, then your code will automatically work on all related distros. If you detect the dpkg database, your code will work on Debian, Ubuntu, Linux Mint, and the many other distros based on Debian. If you detect the rpm database, your code will work on Red Hat, Centos, Fedora, Mandriva, and all the many other distros based on RPM.

steveha
  • 74,789
  • 21
  • 92
  • 117
  • The problem here is that some packages have different names or are not available at all. That's why I still need the distri name. But nevertheless - if the script finds zypper, it is probably SuSE, so thanks for that ;) – Slesa Apr 05 '20 at 09:11
7

If the distribution follows the Linux Standard Base, you could read the output of lsb_release -i.

Something like this:

import os

try:
    distro = os.popen('lsb_release -i').read().split(':')[1].strip()
except IndexError:
    distro = None
ʇsәɹoɈ
  • 22,757
  • 7
  • 55
  • 61
1

This little bit of Python boilerplate will print out your platform information:

import platform  

print platform.linux_distribution()  
('openSUSE ', '11.4', 'x86_64')  

should do the job.

octopusgrabbus
  • 10,555
  • 15
  • 68
  • 131
karolus
  • 11
  • 1
  • 1
    Today, 2020/04/05: AttriubuteError: module 'platform' has no attribute 'linux_distribution'. This is strange, I think it once had this attrib. But even with uname -a, there is no hint anymore that the underlying system is a SuSE. – Slesa Apr 05 '20 at 09:15
0

Output of os.uname():

('Linux',
 'i7',
 '2.6.32-41-generic',
 '#90-Ubuntu SMP Tue May 22 11:31:25 UTC 2012',
 'i686')

The uname -a command should give you much of the same information.

% uname -a
Linux i7 2.6.32-41-generic #90-Ubuntu SMP Tue May 22 11:31:25 UTC 2012 i686 GNU/Linux

then

distr = os.popen('uname -a').read().split()

gives you:

['Linux',
 'i7',
 '2.6.32-41-generic',
 '#90-Ubuntu',
 'SMP',
 'Tue',
 'May',
 '22',
 '11:31:25',
 'UTC',
 '2012',
 'i686',
 'GNU/Linux']

And you can pick the relevant fields you need.

I am assuming the uname -a command provides somewhat uniform output for the distributions. If not, then this won't work.

Levon
  • 138,105
  • 33
  • 200
  • 191
  • Why the downvote? I'm happy to correct any errors or improve the answer, or withdraw it, but I need to know what the perceived problem is *first*. – Levon Jun 17 '12 at 20:12
  • 3
    1. Suse doesn't have its name in uname -a – unbeli Jun 17 '12 at 20:13
  • 1
    @unbeli I appreciate the first comment (what does SUSE display for `uname -a`)?, your 2nd comment is rude and out of line. – Levon Jun 17 '12 at 20:17
  • As for OpenSUSE uname -a, it's not that hard to google a sample: Linux pax22 3.1.0-1.2-default #1 SMP Thu Nov 3 14:45:45 UTC 2011 (187dde0) i686 i686 i386 GNU/Linux. As you can see, no indication of distribution, so your answer kinda does not work. Sorry. – unbeli Jun 17 '12 at 20:27
  • 1
    SUSE and many other Unix Distros have the same uname -a output! – ant0nisk Jun 20 '12 at 10:14