0

I am trying to beautify the output of different system commands, but since I am using a non Redhat based OS my program snags executing the rpm feature. Could someone give a nudge in the right direction, I would like to make this more Pythonic and implement error checking against the rpm function if not a RH based OS.

def kernVer(kern1, kern2, kern3, kern4):
    if subprocess.check_output(["uname", "-a"]).decode('ascii').strip():
        print ('\x1b[6;30;42m' + '[✔] %s [✔]' % (kern1) + '\x1b[0m')
    if subprocess.check_output(["uname", "-mrs"]).decode('ascii').strip():
        print ('\x1b[6;30;42m' + '[✔] %s [✔]' % (kern2) + '\x1b[0m')
    if subprocess.check_output(["cat", "/proc/version"]).decode('ascii').strip():
        print ('\x1b[6;30;42m' + '[✔] %s' % (kern3) + '\x1b[0m')
    if subprocess.check_output(["rpm", "-q","kernel"]).decode('ascii').strip():
        print ('\x1b[6;30;42m' + '[✔] %s [✔]' % (kern4) + '\x1b[0m')
    else:
        print ('\x1b[1;32;41m' + '[✘] Unable To Obtain Kernel Version! [✘]' + '\x1b[0m')
        return

traceback from Atto Allas’s code:

   Traceback (most recent call last):
  File "Kern_Func_2.py", line 40, in <module>
    main()
  File "Kern_Func_2.py", line 35, in main
    kernel_info = get_kern_info()
  File "Kern_Func_2.py", line 20, in get_kern_info
    return_val = subprocess.check_output(command)
  File "/usr/lib/python3.5/subprocess.py", line 316, in check_output
    **kwargs).stdout
  File "/usr/lib/python3.5/subprocess.py", line 383, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.5/subprocess.py", line 676, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.5/subprocess.py", line 1289, in _execute_child
    raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'cat /proc/version'

I have also included an image of what is currently working in my program and to better illustrate desire results, including the kernels. I hope this better helps illustrate the dilemma.
enter image description here

1 Answer 1

1

In my opinion, using a specific try: and except: is the most 'pythonic' way to do it. See the following example:

Replace:

if subprocess.check_output(["rpm", "-q","kernel"]).decode('ascii').strip():
    print ('\x1b[6;30;42m' + '[✔] %s [✔]' % (kern4) + '\x1b[0m')
else:
    print ('\x1b[1;32;41m' + '[✘] Unable To Obtain Kernel Version! [✘]' + '\x1b[0m')
    return

With:

try:
    subprocess.check_output(["rpm", "-q","kernel"]).decode('ascii').strip()
    print('\x1b[6;30;42m' + '[✔] %s [✔]' % (kern4) + '\x1b[0m')
except subprocess.CalledProcessError:
    print('\x1b[1;32;41m' + '[✘] Unable To Obtain Kernel Version! [✘]' + '\x1b[0m')
    return

or alternatively,

popen_check = subprocess.Popen(["rpm", "-q","kernel"])
popen_check.communicate()

if popen_check.returncode == 127: #127 is the command not found code
    print('\x1b[1;32;41m' + '[✘] Unable To Obtain Kernel Version! [✘]' + '\x1b[0m')
else:
    print('\x1b[6;30;42m' + '[✔] %s [✔]' % (kern4) + '\x1b[0m')

Note: I do not think your code will work, but this is how you would write your code, if it were correct. Also, I cannot write this code for you, because I don't actually know what you are trying to achieve.

An example of what your code might look like is this:

import subprocess

def get_kern_info():
    command_lists = [["uname", "-a"], ["uname", "-mrs"], ["cat /proc/version"], ["rpm", "-q","kernel"]]
    # cat is only one command because on some implementations, it breaks if the filepath is not directly in the same string as cat

    return_values = []

    for command in command_lists:
        try:
            return_val = subprocess.check_output(command)
            formatted_val = return_val.decode('ascii').strip()

            if formatted_val != '':
                return_values.append(formatted_val)
            else:
                return_values.append(str(command)+’ outputted nothing!’)

        except subprocess.CalledProcessError:
            return_values.append(str(command)+’ could not be called!’)
            continue

    return return_values

def main():
    kernel_info = get_kern_info()

    print("The data I got was: \n" + '\n'.join(kernel_info))

main()

Sample output from Windows bash terminal:

Windows bash output

Hope this helps!

Sign up to request clarification or add additional context in comments.

15 Comments

Atto Allas, I appreciate the help, but like you mentioned I believe my approach is flawed and I am still unable to get the desired results. I am attempting to use the subprocess call to check the kernel version, if present and output it with print using hex to color code version(s) found, but since I am using a debian based OS at the moment, it will obviously error out on the rpm request. I was hoping to make it a universal script, by skipping kernels not present on the machine and reporting only versions found. Also, I thought calling it through a class would be best to keep it tidy
@th0r Just checking, do you want the function to output ALL of the data it can find (i.e. if it's a standard debian system, it would print 3 things) or just the first one it can find?
I would like it to print ALL output it can find, yes. So, as you stated Debian based OS would find the first three, 'uname -a', 'uname -mrs', 'cat /proc/version' and skip RPM if not found on the system. Trying to make the script universal as possible, as I add upon it. Thanks for any guidance.
@th0r Updated my answer. I hope it helps (I have not been able to thoroughly test it as at the moment I am on my Windows partition)
I really appreciate the help, but the code executes(no errors), but returns no output. I will tinker with the previous examples and the latest provided example and hopefully figure it out or just take out the rpm call. Thanks again for taking time to help.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.