首页 > 解决方案 > Python子进程不打印vnstat进程

问题描述

感谢您花时间阅读这篇文章。

我正在尝试使用 vnstat 在 python 中进行实时带宽监控。不幸的是,它没有打印我想要的输出,我似乎无法弄清楚为什么。这是我下面的代码。

from subprocess import Popen, PIPE
import time

def run(command):
 process = Popen(command, stdout=PIPE, bufsize=1, shell=True ,universal_newlines=True)
 while True:
    line = process.stdout.readline().rstrip()
    print(line)



if __name__ == "__main__":
 run("sudo vnstat -l -i wlan1") 

当我在终端中运行此代码时,这是我得到的输出:

sudo python testingLog.py
Monitoring wlan1...    (press CTRL-C to stop)

在终端中运行“vnstat -l -i wlan1”时,它没有向我显示所需的输出。

期望的输出:

Monitoring wlan1...    (press CTRL-C to stop)

rx:        0 kbit/s     0 p/s          tx:        0 kbit/s     0 p/s

当我运行 vnstat -l -i wlan1 时会发生什么,它会更新它并实时运行,所以我怀疑我的打印是错误的,因为它没有打印所需的输出,但我似乎无法弄清楚原因。

标签: python

解决方案


并不是您的打印错误,而是vnstat不断更新同一行而不发布新行,因此process.stdout.readline()在某一点挂起,等待永远不会出现的新行。

如果您只想将vnstatSTDOUT 重定向到 Python 的 STDOUT,您可以通过管道传输它,即:

import subprocess
import sys
import time

proc = subprocess.Popen(["vnstat", "-l", "-i", "wlan1"], stdout=sys.stdout)
while proc.poll() is None:  # loop until the process ends (kill vnstat to see the effect)
    time.sleep(1)  # wait a second...
print("\nProcess finished.")

但是,如果您想捕获输出并自己处理它,则必须同时流式传输STDOUTa 字符(或安全缓冲区)以捕获任何vnstat发布的内容,然后决定如何处理它。例如,要模拟上述管道,但您坐在驾驶座上,您可以执行以下操作:

import subprocess
import sys

proc = subprocess.Popen(["vnstat", "-l", "-i", "wlan1"], stdout=subprocess.PIPE)
while True:  # a STDOUT read loop
    output = proc.stdout.read(1)  # grab one character from vnstat's STDOUT
    if output == "" and proc.poll() is not None:  # process finished, exit the loop
        break
    sys.stdout.write(output)  # write the output to Python's own STDOUT
    sys.stdout.flush()  # flush it...
    # of course, you can collect the output instead of printing it to the screen...
print("\nProcess finished.")

推荐阅读