如何从subprocess.Popen得到输出()。 proc.stdout.readline(

2019-07-05 08:46发布

我想从输出执行Test_Pipe.py,我尝试下面的代码的Linux,但没有奏效。

Test_Pipe.py

import time
while True :
    print "Someting ..."
    time.sleep(.1)

Caller.py

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()被阻塞,所以没有数据被打印出来。

Answer 1:

你明明可以使用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()


Answer 2:

Nadia的片断的工作,但有1个字节的缓冲区调用read是非常不推荐的。 更好的方式来做到这将是标准输出文件描述符设置为使用非阻塞的fcntl

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/


Answer 3:

为了避免总是可以缓冲的任务,如“让子进程的输出实时主进程”出现的很多问题,我总是建议使用Pexpect的所有非Windows平台, wexpect在Windows,而不是subprocess时,这样的任务是期望的。



Answer 4:

Test_Pipe.py缓存默认情况下它的标准输出使procCaller.py没有看到任何输出,直到孩子的缓冲区满(如果缓冲区大小为8KB则大约需要一分钟时间填写Test_Pipe.py的标准输出缓冲)。

为了使输出无缓冲(行缓冲用于文本流),你可以通过-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的子进程的块缓冲问题。



文章来源: How to get output from subprocess.Popen(). proc.stdout.readline() blocks, no data prints out