我想从执行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()
行已被屏蔽,因此无法打印出数据。
答案 0 :(得分:43)
你显然可以使用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()
答案 1 :(得分:21)
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按照提供的方式工作。
答案 2 :(得分:13)
为了避免缓慢执行诸如“将子进程的输出实时输出到主进程”等任务的许多问题,我总是建议对所有非Windows平台使用pexpect {{ 3}}在Windows上,而不是subprocess
,当需要这样的任务时。
答案 3 :(得分:13)
Test_Pipe.py
默认缓冲其stdout,因此proc
中的Caller.py
在子缓冲区已满之前看不到任何输出(如果缓冲区大小为8KB则需要大约一分钟填写Test_Pipe.py
的stdout缓冲区。)
要使输出无缓冲(对文本流进行行缓冲),您可以将-u
flag传递给子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: read streaming input from subprocess.communicate()中有关如何解决非Python子进程的块缓冲问题的链接。