简体   繁体   中英

How can i use python to read output of linux program (top)

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.

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

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:])

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'])

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

top -l 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM