【问题标题】:How can i use python to read output of linux program (top)如何使用 python 读取 linux 程序的输出(顶部)
【发布时间】:2017-11-23 17:12:29
【问题描述】:

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

我在 python 文档中阅读了关于 subprocess 模块的使用,但这似乎无法正常工作。那是因为当你在 linux 中运行 top 命令时,你会得到一个不断刷新的活跃窗口。 “top”与“ls”或“cp”不同。

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

提前致谢。

【问题讨论】:

  • 到目前为止您尝试过什么? (顺便说一句,很可能通过管道(stdin)从顶部获取输出,但您将获得持续更新,因此您需要阅读一段时间,然后停止。)
  • 如果你运行 'top -n 1' 它将显示当前进程而不刷新。对于文件的统计信息,使用 os.stat()。
  • 您可以在批处理模式下运行 top -b 并解析输出。或者您可以阅读有关 /proc 文件系统的信息。

标签: python linux subprocess system


【解决方案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

【讨论】:

    【解决方案2】:

    如果在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:])
    

    【讨论】:

      【解决方案3】:

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

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

      如果你真的想使用top,你需要传递-b 选项(批处理模式)

      来自手册页

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

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

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

      【讨论】:

        【解决方案4】:

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

        top -l 1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-10
          • 1970-01-01
          • 2013-01-14
          相关资源
          最近更新 更多