我试图弄清楚如何在 python 中处理进程的实时、持续的输出。 我的队友给了我一个脚本,我们称之为 applicationAPI.py,它执行以下操作:
我想做的是从这个过程中捕获实时输出数据,并在我自己的 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 秒的时间间隔内,它将继续向标准输出输出数据。但它永远不会返回返回代码或完成执行。我尝试重定向到一个文件,但同样,因为它是相同的过程,所以输出文件会永远增长。我不知道如何捕获或操作这些数据,以便我可以在脚本中解析它。
您可以使用较低级别的
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 字节,但它取决于系统)。有时程序包含一个标志,告诉它在每个换行符上刷新标准输出。也许这个程序有一个或者可以实现?