在脚本内处理实时过程输出数据?

问题描述 投票:0回答:1

我试图弄清楚如何在 python 中处理进程的实时、持续的输出。 我的队友给了我一个脚本,我们称之为 applicationAPI.py,它执行以下操作:

  1. 建立与主机设备的 TCP 连接
  2. 定义了从主机设备上的应用程序中提取的许多指标
  3. 在定义的时间间隔内以 CSV 格式实时将这些指标输出到我的标准输出,在本例中为每 60 秒。

我想做的是从这个过程中捕获实时输出数据,并在我自己的 python 脚本中解析它。我尝试使用以下子进程

import subprocess
import csv
import json

api_call = subprocess.run(['./applicationAPI.py', '-target_ip', '-username', 
'-password', 'metric1', 'metric2', 'metric3', '-u', '60'], capture_output=True, text=True, check=True)

api_response = (api_call.stdout)
f = StringIO(api_response)
reader = csv.reader(f)
for line in reader:
    print(line)

但它不起作用。问题是这个过程正在进行中。在 60 秒的时间间隔内,它将继续向标准输出输出数据。但它永远不会返回返回代码或完成执行。我尝试重定向到一个文件,但同样,因为它是相同的过程,所以输出文件会永远增长。我不知道如何捕获或操作这些数据,以便我可以在脚本中解析它。

python python-3.x csv subprocess
1个回答
0
投票

您可以使用较低级别的

Popen
类,它为您提供
stdout
stderr
管道来读取。启动进程时将 stderr 重定向到文件,然后从 stdout 读取 csv 信息,直到完成。最后等待进程结束并读取返回码。

import subprocess
import csv
import json
import tempfile

with tempfile.TemporaryFile() as stderr_file:

    api_call = subprocess.Popen(['./applicationAPI.py', '-target_ip', '-username',
        '-password', 'metric1', 'metric2', 'metric3', '-u', '60'],
        stdout=subprocess.PIPE, stderr=stderr_file)
    for row in csv.reader((line.decode() for line in api_call.stdout)):
        print(row)
    api_call.wait()
    if api_call.returncode != 0:
        stderr_file.seek(0)
        print(stderr_file.read())

这不是实时的。因为您使用的是管道,而不是终端,所以程序将缓冲标准输出。您只会看到块大小边界上的输出(可能每 2048 字节,但它取决于系统)。有时程序包含一个标志,告诉它在每个换行符上刷新标准输出。也许这个程序有一个或者可以实现?

© www.soinside.com 2019 - 2024. All rights reserved.