Bottom Page

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Getting wanted data from the 'top' command (Linux)
#1
This script gets system data from Linux top command: load averages, number of users, and top processes' PID, USER, CPU%, and Command Path. url is also here.

#! /usr/bin/python3
from os import popen
import pprint


class Top:
    def __init__(self):
        self.general_sys_info = {
            'number_of_users': '',
            'load_averages': []
        }
        self.process = {
            'pid': '',
            'user': '',
            'cpu_percentage': '',
            'command_path': ''
        }

    def __start_process(self):
        for line in popen('top -n 1 -bc | head -15'):
            if len(line.split()) != 0:
                yield line.split()

    def run_top(self):
        first_elements = ['Tasks:', '%Cpu(s):', 'KiB', 'PID']
        for line_list in self.__start_process():
            if line_list[0] not in first_elements:
                if line_list[0] != 'top':
                    self.process['pid'] = line_list[0]
                    self.process['user'] = line_list[1]
                    self.process['cpu_percentage'] = line_list[8]
                    self.process['command_path'] = ' '.join(line_list[11:])
                    yield self.process
                else:
                    self.general_sys_info['number_of_users'] = line_list[5]
                    self.general_sys_info['load_averages'] = line_list[9:12]
                    yield self.general_sys_info


if __name__ == "__main__":
    pp = pprint.PrettyPrinter(indent=4)
    for system_info in Top().run_top():
        pp.pprint(system_info)
        print('\n')

I am kinda hoping someone might chime in...

In the client of the script... is there a better way to print the key/value pairs from a generator object?
I tried the usual .items() method and the iter() keyword but didn't work:

for k,v in Top().run_top().items():
    print(k)
    print(v)
and...

for k,v in iter(Top().run_top().items()):
    print(k)
    print(v)
Not much luck though
Gribouillis and Larz60+ like this post
Quote
#2
(Nov-08-2018, 09:56 PM)rootVIII Wrote: is there a better way to print the key/value pairs from a generator object?
You can try
from itertools import chain
for k, v in chain.from_iterable(info.items() for info in Top().run_top()):
    print(k)
    print(v)
Quote
#3
Ah that's perfect! Thanks

Thanks again... Here's what I ended up using:

    for k, v in enumerate(chain.from_iterable(info.items() for info in Top().run_top())):
        if k < 2 or 'command_path' in v:
            print("%s: %s\n" % (v[0],  v[1]))
        else:
            print("%s: %s" % (v[0], v[1]))

Quote
#4
forgot to post the completed version:

#! /usr/bin/python3
# get system data from top: load averages, number of users,
# and top processes' PID, USER, CPU%, and Command Path
from os import popen
from itertools import chain


class Top:
    def __init__(self):
        self.general_sys_info = {
            'number_of_users': '',
            'load_averages': []
        }
        self.process = {
            'pid': '',
            'user': '',
            'cpu_percentage': '',
            'command_path': ''
        }

    def __start_process(self):
        for line in popen('top -n 1 -bc | head -15'):
            if len(line.split()) != 0:
                yield line.split()

    def run_top(self):
        first_elements = ['Tasks:', '%Cpu(s):', 'KiB', 'PID']
        for line_list in self.__start_process():
            if line_list[0] not in first_elements:
                if line_list[0] != 'top':
                    self.process['pid'] = line_list[0]
                    self.process['user'] = line_list[1]
                    self.process['cpu_percentage'] = line_list[8]
                    self.process['command_path'] = ' '.join(line_list[11:])
                    yield self.process
                else:
                    self.general_sys_info['number_of_users'] = line_list[5]
                    self.general_sys_info['load_averages'] = line_list[9:12]
                    yield self.general_sys_info


if __name__ == "__main__":
    for k, v in enumerate(chain.from_iterable(i.items() for i in Top().run_top())):
        if k < 2 or 'command_path' in v:
            print("%s: %s\n" % (v[0],  v[1]))
        else:
            print("%s: %s" % (v[0], v[1]))

Quote
#5
Good one!

How about reading the data straight from /proc?
I was tried to research where are all the data I want to get from /proc but I didn't manage to learn enough. Perhaps I have to dig deeper.

Right now I am just reading the cpu cores temperature.
rootVIII likes this post
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Quote
#6
wavic Wrote:Right now I am just reading the cpu cores temperature.
Aren't you reinventing the wheel? We already have psutil.sensors_temperatures()
rootVIII likes this post
Quote

Top Page

Possibly Related Threads...
Thread Author Replies Views Last Post
  Linux user folder names (if translated) Axel_Erfurt 0 120 Sep-23-2018, 05:55 PM
Last Post: Axel_Erfurt
  ptb.py - process trace back for linux Skaperen 3 467 Feb-06-2018, 08:56 AM
Last Post: Gribouillis
  Watch files and automatically run a script in Linux Gribouillis 3 740 Jan-23-2018, 06:50 PM
Last Post: nilamo
  ATA Pass-Through library for linux kazenniy 0 871 Nov-07-2016, 08:36 AM
Last Post: kazenniy
  msvcrt.getkey for linux metulburr 0 3,165 Nov-03-2016, 08:18 PM
Last Post: metulburr

Forum Jump:


Users browsing this thread: 1 Guest(s)