python os.popen().read()没有数据_关于python:如何从subprocess.Popen()获取输出。 proc.stdout.readline()块,没有数据打印出来...

2023-05-16

我需要执行Test_Pipe.py的输出,我在Linux上尝试了以下代码,但没有用。

Test_Pipe.py

import time

while True :

print"Someting ..."

time.sleep(.1)

来电者

import subprocess as subp

import time

proc = subp.Popen(["python","Test_Pipe.py"], stdout=subp.PIPE, stdin=subp.PIPE)

while True :

data = proc.stdout.readline() #block / wait

print data

time.sleep(.1)

proc.stdout.readline()行被阻止,因此没有数据打印出来。

重复:stackoverflow.com/search?q=%5Bpython%5D+subprocess+output,stackoverflow.com/questions/803265/,stackoverflow.com/questions/1277866/

您显然可以使用subprocess.communicate,但我认为您正在寻找实时输入和输出。

readline被阻止,因为该过程可能正在等待您的输入。您可以逐个字符地阅读以克服此问题,如下所示:

import subprocess

import sys

process = subprocess.Popen(

cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE

)

while True:

out = process.stdout.read(1)

if out == '' and process.poll() != None:

break

if out != '':

sys.stdout.write(out)

sys.stdout.flush()

在这种情况下,您不需要process.poll()。

Nadia的代码片段确实可以工作,但是不建议使用1字节缓冲区调用read。更好的方法是使用fcntl将stdout文件描述符设置为非阻塞

fcntl.fcntl(

proc.stdout.fileno(),

fcntl.F_SETFL,

fcntl.fcntl(proc.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK,

)

然后使用select测试数据是否准备就绪

while proc.poll() == None:

readx = select.select([proc.stdout.fileno()], [], [])[0]

if readx:

chunk = proc.stdout.read()

print chunk

她是正确的,因为您的问题必须与您按照Caller.py和Test_Pipe.py的规定工作时发布的问题不同。

https://derrickpetzold.com/p/capturing-output-from-ffmpeg-python/

由于块缓冲问题,它不会比问题中的代码更早产生输出。看我的答案。

该代码确实会实时产生输出。你有问题吗?

按照评论中的链接。

数据"准备就绪"是什么意思?它是用换行符描绘的,还是仅准备好至少一个字节的数据(即使此类数据的生产者仍在向其stdout写入数据)?

@me,J.F. Sebastians下面的答案解决了这个问题。

需要明确的是:由于子进程中的内部缓冲区,您的答案和Nadias的答案都不会"实时"生成输出。代码(在父进程中)中的os.O_NONBLOCK对子进程中的内部stdio缓冲区没有影响。例如,运行代码将产生4K块,而不是len(chunk) == 13(一行)。若要查看差异,请传递-u选项(运行[sys.executable or python2, -u, Test_Pipe.py]命令)。

Test_Pipe.py默认情况下会缓冲其stdout,因此Caller.py中的proc在子缓冲区已满之前不会看到任何输出(如果缓冲区大小为8KB,则填充Test_Pipe.py的stdout缓冲区大约需要一分钟)。

要使输出无缓冲(文本流为行缓冲),可以将-u标志传递给子Python脚本。它允许"实时"逐行读取子流程的输出:

import sys

from subprocess import Popen, PIPE

proc = Popen([sys.executable,"-u","Test_Pipe.py"], stdout=PIPE, bufsize=1)

for line in iter(proc.stdout.readline, b''):

print line,

proc.communicate()

请参阅Python中的链接:从subprocess.communicate()读取流输入,以了解如何解决非Python子进程的块缓冲问题。

同样,您使用的是1个字节的缓冲区,效率非常低。

@DerrickPetzold:错了。 bufsize=1表示"行缓冲"。它使用与bufsize=-1相同的缓冲区大小。您可能已经发现,如果您实际上是在运行代码,则两个注释都是错误的(比较时间性能并测量读取第一个字节之前的时间)

我喜欢这种方式,因为您可以直接在屏幕上打印,也可以存储popen的结果以进行某些处理,然后再检查错误代码等... ...竖起大拇指=)我用bufsize来运行它并执行在我的代码中对我来说工作正常。

为了避免为任务缓冲(例如"将子进程的输出实时获取到主进程的实时信息")缓冲时常会出现许多问题,我始终建议对所有非Windows平台使用wespect,而不是subprocess ,当需要执行此类任务时。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python os.popen().read()没有数据_关于python:如何从subprocess.Popen()获取输出。 proc.stdout.readline()块,没有数据打印出来... 的相关文章

随机推荐