1

after struggling trying to figure out how to use python to save the output of the "top" linux command to a variable and then using grep to get a line, I couldn't make it.

I have read in the python documentation about the use of the subprocess module but this doesn't seem to work properly. That is because when you run the top command in linux, you get an alive windows that is refreshing continuously. "Top" is not the same as "ls" or "cp".

So my question is this: How can i use python to get system statistics like CPU percentages etc? (preferebly using the top command, but it would be okay if i would use another command or if i were to read the statistics from a file)

Thanks in advance.

4
  • What have you tried so far? (It is, by the way, very possible to get the output from top through a pipe (stdin) but you will get continuous updates, so you need to read for a while, then stop.) Commented Nov 23, 2017 at 18:08
  • If you run 'top -n 1' it will display the current processes without refreshing. For the statistics of a file, use os.stat(). Commented Nov 23, 2017 at 18:18
  • You can run top in batch mode -b and parse the output. Or you can read about the /proc filesystem. Commented Nov 23, 2017 at 18:22
  • or u can use this package to parse for you github.com/sweetim/linux-top-parser Commented Mar 3, 2023 at 16:00

4 Answers 4

3

If getting process information in Python, @LeGre is correct, you should use the psutil library

However, to answer the more general quesion of "How can i use python to read output of linux program", I will use top as an example. This methodology could be used for any fixed width text source.

Note: This example should work on Linux 5.3 (Ubuntu 18.04). Other distributions may have different column offsets or columns headings. Adjust as required.

import subprocess, sys, re
from io import StringIO
import pandas as pd

def main(argv):
    output = subprocess.check_output(['top', "-bn1", "-o", "%MEM"])

    match = re.match(r'^[\w\W]*?\n( +PID.*COMMAND)\n([\w\W]*)', output.decode())

    header = match[1]
    data = match[2]

    df = pd.read_fwf( StringIO(data)
        , colspecs = [(0,5), (6,16), (16,18), (19,22), (23,30), (31,37), (38,44), (45,46), (47,52), (53,57), (58,67), (68,999) ]
        , names    = ['PID', 'USER',    'PR',    'NI',  'VIRT',   'RES',   'SHR',     'S',  '%CPU',  '%MEM', 'TIME+', 'COMMAND']
    )

    print(df.to_dict(orient='index'))


if __name__ == '__main__':
    main(sys.argv[1:])
Sign up to request clarification or add additional context in comments.

Comments

2

Try using -b and -n to get output from top:

-b  :Batch-mode operation
    Starts top in Batch mode, which could be useful for sending output
    from top to other programs or to a file.  In this mode, top will
    not accept input and runs until the iterations limit you've set
    with the `-n' command-line option or until killed.

-n  :Number-of-iterations limit as:  -n number
    Specifies the maximum number of iterations, or frames, top should
    produce before ending.

For example:

$ top -b -n 1

Comments

1

top by default uses ncurses so getting output from it will be tricky.

Python has a package called psutil. You should use that instead.

If you really want to use top you'll need to pass the -b option (batch mode)

From the manpage

In this mode, top will not accept input and runs until the iterations limit you've set with the -n command-line option or until killed.

So you can try something like this

>>> output = subprocess.check_output(['top', '-b', '-n1'])

Comments

0

samples option of top command allows sampling n-times. So, following command runs only one time and breaks after that:

top -l 1

Comments

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.