我如何使用python来读取linux程序的输出(上)

时间:2017-11-23 17:12:29

标签: python linux subprocess system

在努力弄清楚如何使用python将“top”linux命令的输出保存到变量然后使用grep获取一行之后,我无法做到。

我已经在python文档中读到了有关子进程模块的使用但这似乎无法正常工作。那是因为当你在linux中运行top命令时,你会得到一个持续刷新的活动窗口。 “Top”与“ls”或“cp”不同。

所以我的问题是: 如何使用python获取CPU百分比等系统统计信息? (最好使用top命令,但如果我使用另一个命令或者如果我要从文件中读取统计信息那就没关系)

提前致谢。

4 个答案:

答案 0 :(得分:1)

尝试使用-b-n从顶部获取输出:

-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.

例如:

$ top -b -n 1

答案 1 :(得分:1)

top默认使用ncurses,因此从中获取输出会很棘手。

Python有一个名为psutil的包。你应该改用它。

如果您真的想使用top,则需要通过-b选项(批处理模式)

从联机帮助页

  

在此模式下,top将不接受输入并运行,直到迭代限制您使用-n命令行选项设置或直到被杀死。

所以你可以尝试这样的事情

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

答案 2 :(得分:0)

samples top选项允许采样n次。因此,以下命令只运行一次并在此之后中断:

top -l 1

答案 3 :(得分:0)

如果在Python中获取过程信息,@ LeGre是正确的,则应使用psutil

但是,要回答“如何使用python读取linux程序的输出”这一更普遍的问题,我将以 top 为例。这种方法可用于任何固定宽度的文本源。

注意:此示例应在Linux 5.3(Ubuntu 18.04)上运行。其他分布可能具有不同的列偏移量或列标题。根据需要进行调整。

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