-2

pulling hair out. (sorry frustrated)

ok, so i'm trying to do an if: else in python, only i can't get it to work properly so i'm hoping that someone can help. i'll try and be as specific as possible.

what i'm tring to do -> i'm assigning a variable to check if something is true, sometimes it is sometimes it's not.

if that variable is true then i want it to skip the else statement and print out the result. (once fully implemented it will return resutlt to script instead of printing)

python code:

import re

os_version = open('/etc/os-release')
for line in os_version:
    OS = re.search(r'\AID_LIKE=\D[A-Za-z]+', line)
    if OS:
        print(str(OS.group()).lstrip('ID_LIKE="'))
    else:
        OS = re.search(r'\AID=\D[A-Za-z]+', line)
        print(str(OS.group()).lstrip('ID="'))

when i run it like this i get a NoneType object has no group

if i have an if OS: statement indented under the else, before the print, then i get both results back, even if i have a 'break' after the first print

depending on what platform of linux that i'm running on will depend on what the results should be.

example (bash code)

#!/bin/bash

VAR0=`cat /etc/os-release | grep -w ID_LIKE | cut -f2 -d= |\
    tr -d [=\"=] | cut -f1 -d' '`
VAR0="${VAR0:=`cat /etc/os-release | grep -w ID | cut -f2 -d= |\
    tr -d [=\"=]`}"
echo $VAR0

if [ "$VAR0" = 'debian' ]; then
    echo 'DEBIAN based'
elif [ "$VAR0" = 'rhel' ]; then
    echo 'RHEL based'
elif [ "$VAR0" = 'suse' ]; then
    echo 'SUSE based'
else echo 'OTHER based'

fi

this is the return that comes back from the bash code->

bash -o xtrace os-version.sh 
++ cat /etc/os-release
++ grep -w ID_LIKE
++ cut -f2 -d=
++ tr -d '[="=]'
++ cut -f1 '-d '
+ VAR0=rhel
+ VAR0=rhel
+ echo rhel
rhel
+ '[' rhel = debian ']'
+ '[' rhel = rhel ']'
+ echo 'RHEL based'
RHEL based

from a different os->

bash -o xtrace test_2.sh 
++ tr -d '[="=]'
++ cut -f1 '-d '
++ cut -f2 -d=
++ grep -w ID_LIKE
++ cat /etc/os-release
+ VAR0=
++ tr -d '[="=]'
++ grep -w ID
++ cut -f2 -d=
++ cat /etc/os-release
+ VAR0=debian
+ echo debian
debian
+ '[' debian = debian ']'
+ echo 'DEBIAN based'
DEBIAN based

as you can see the VAR0 on the first run is empty and it then goes to the second.

that's what i'm trying to do with python.

can someone help? i have a feeling that i'm just overlooking something simple after starting at the screen for so long.

thanks

em

edit for joel:

my code now and the results=> code:

#!/usr/bin/python3

import re

os_version = open('/etc/os-release')
for line in os_version:
    OS = re.search(r'\AID_LIKE=\D[A-Za-z]+', line)
    if OS:
        print(str(OS.group()).lstrip('ID_LIKE="'))
        break
    else:
        OS = re.search(r'\AID=\D[A-Za-z]+', line)
            if OS:
            print(str(OS.group()).lstrip('ID="'))

results from a debian system=>

python test.os-version_2.py 
debian

results from a debian based system=>

python test.os-version_2.py 
raspbian
debian

results from centos7=>

python test.os-version_2.py 
centos
rhel

results from opensuse=>

python test.os-version_2.py 
opensuse
suse

results from linuxmint(what i'm running now, even though it's ubuntu/debian basied)=>

python test.os-version_2.py 
linuxmint

so since some things are responding differently and there are so many different distro's based off of a couple, i'm trying to narrow down the results to the fewest possible.

each one has a different way that they do things and to try and get a script that is cross platform working as best as it can, i'm trying to narrow things down.

if you 'cat /etc/os-release' you will see that different os's display things differently.

edit answer:

i don't know why this is yet for me putting a variable to the print statements and then printing the variable it's working. maybe someone can answer that for me.

answer code:

#!/usr/bin/python3

import re

os_version = open('/etc/os-release')
for line in os_version:
    OS = re.search(r'\AID_LIKE=\D[A-Za-z]+', line)#.group()
    if OS is not None:
        base_distro = (str(OS.group()).lstrip('ID_LIKE="'))
    else:
        OS = re.search(r'\AID=\D[A-Za-z]+', line)#.group()
        if OS is not None:
            base_distro = (str(OS.group()).lstrip('ID="'))

print(base_distro)

if you put that into a script and then run it you will see what i'm looking for.

thanks everyone for helping

emetib
  • 23
  • 6
  • i should add that i'm somewhat new to this stuff. can read programming pretty well, yet can't get my brain to write it. – emetib Aug 12 '16 at 03:37
  • 1
    Could you clarify which line is giving the error? It's almost certainly that your OS variable is unexpectedly set to None, and/or your "print" indentation is off. – Joel Harmon Aug 12 '16 at 03:44
  • 2
    you are trying to get linux distro name, so check this question http://stackoverflow.com/q/2756737/1040495 – user1040495 Aug 12 '16 at 03:51
  • Jjpx, i looked at that and it's somewhat on the right track. yet as the commenters have said, that's depreciated. didn't run it since i'm trying to get this running under 3.x – emetib Aug 12 '16 at 04:05
  • 1
    You're assuming the system _has_ an `/etc/os-release` file. Not all Linux systems do. – Kevin J. Chase Aug 12 '16 at 06:04
  • that is true. maybe i should just look at the log dir to find what i'm looking for. i know what/where the big three keep what i'm looking for. i just thought finding what distro the running system is based on would be less overhead in the long run. – emetib Aug 13 '16 at 14:02

1 Answers1

1

Getting the system platform is easy with Python 2.7 see platform import

import platform

print platform.dist()[0],type(platform.dist()[0])

returns

debian <type 'str'>

On my platform.

To clarify - OS = re.search(r'\AID_LIKE=\D[A-Za-z]+', line) returns an object (NoneType)

Note "import platform" will be depreciated. Below is method with the new way (just a basic method, might not be suitable to all situations, but it works for what i think you have described - to do your comparisons, just use a dict like in the comments

Edit - Super simple way - using subprocess if platform doesn't work

import subprocess

output = subprocess.check_output(["cat", "etc/os-release"])
with open('text.txt', 'w+') as fd:
    fd.write(output)
with open('text.txt', 'r') as text_output:
    for os_version in text_output:
       try:
           print os_version.split("ID_LIKE=",1)[1]
       except:
           continue

Here we just call the actual command, take the output as a string, chuck it in a file, and read all the lines, splice the line at the key word we want and bam! Want the OS ID? Then add print os_version.split("ID=",1)[1]

Again the output is: debian raspberry pi

itza
  • 58
  • 5
  • try that on a centos, opensuse distro. what i'm trying to do is to narrow down what the base os is, i.e. debian, red hat, suse, other maybe. – emetib Aug 12 '16 at 04:14
  • Adding `platform.uname()[1]` will return the OS - for my case raspberrypi – itza Aug 12 '16 at 04:32
  • on centos7=>>>> import platform >>> print platform.dist()[0],type(platform.dist()[0]) File "", line 1 print platform.dist()[0],type(platform.dist()[0]) ^ SyntaxError: invalid syntax – emetib Aug 12 '16 at 04:37
  • to expand on what i'm trying to do: if i'm trying to say where to look for something depending on what named distribution that you are running then i have to say-> if debian, then, elif/or raspberry, elif/or ubuntu, elif/or linuxmint, elif/or rhel, elif/or centos, elif/or fedora, elif/or..... if i can narrow it down to the big three right away, wouldn't that be just that much easier? – emetib Aug 12 '16 at 04:41
  • @ementib Deciding what to do based on exactly matching one of a set of strings is _exactly_ the kind of problem a `dict` solves: `os_map = {'debian': deb_func, 'rhel': rh_func, 'fedora': rh_func, ...}` Then, just `os_map.get(os_name, generic_func)(arg0, arg1, ...)`. – Kevin J. Chase Aug 12 '16 at 06:08
  • Official [`platform` module's docs](https://docs.python.org/3/library/platform.html). – Kevin J. Chase Aug 12 '16 at 06:10
  • @ementib i have added an edit with some other code - again tested on my Pi – itza Aug 12 '16 at 06:46