需要强调的是,问题是实时读取而不是非阻塞读取。之前有人问过,例如subprocess.Popen.stdout - 实时读取标准输出(再次)。但是没有提出令人满意的解决方案。
例如,以下代码尝试模拟 python shell。
import subprocess
p = subprocess.Popen(['python'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
while True:
line = input('>>> ')
p.stdin.write(line.encode())
print('>>> ', p.stdout.read().decode())
但是,从p.stdout
. 搜索了一圈后,我发现了以下两种可能的解决方案。
虽然第一个解决方案可能工作并且只在 linux 上工作,但第二个解决方案只是将阻塞读取转换为非阻塞读取,即我无法获得子进程的实时输出。例如,如果我输入 ' ',则使用第二种解决方案print("hello")
将一无所获。p.stdout
也许,有人会建议p.communite
。不幸的是,它不适合这种情况,因为它会关闭标准输入,如此处所述。
那么,有什么适用于Windows的解决方案吗?
已编辑:即使-u
打开并p.stdout.read
替换为p.stdout.readline
,问题仍然存在。
import subprocess
p = subprocess.Popen(['python', '-u'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
while True:
line = input('>>> ')
p.stdin.write(line.encode())
p.stdin.flush()
print('>>> ', p.stdout.readline().decode())
解决方案:以下是基于 JF Sebastian 的回答和评论的最终代码。
from subprocess import Popen, PIPE, STDOUT
with Popen(
['python', '-i', '-q'],
stdin=PIPE, stdout=PIPE, stderr=STDOUT,
bufsize=0
) as process:
while True:
line = input('>>> ')
if not line:
break
process.stdin.write((line+'\n').encode())
print(process.stdout.readline().decode(), end='')
需要注意的是,当命令触发无输出时,程序会挂起。