我正在寻找一个调用另一个脚本并捕获其标准输出的python脚本。被调用的脚本将包含一些输入和输出消息,例如
print ("Line 1 of Text")
variable = raw_input("Input 1 :")
print "Line 2 of Text Input: ", vairable
我正在运行的代码部分是
import subprocess
cmd='testfile.py'
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
so, se = p.communicate()
print(so)
正在发生的问题是stdout在脚本执行之后才会打印。这会留下空白提示,等待用户输入。有没有办法让stdout在被调用脚本仍在运行时打印?
谢谢,
答案 0 :(得分:3)
这里有两个问题。
首先,python将输出缓冲到stdout,你需要阻止它。您可以像{I} Frenkel建议的那样在sys.stdout.flush()
中插入对testfile.py
的调用,或者您可以使用python -u
执行带有无缓冲I / O的testfile.py
。 (参见Ilia链接的other stack overflow question。)
您需要一种从子流程异步读取数据的方法,然后在准备好输入时,打印您读取的数据,以便显示用户的提示。为此,拥有asynchronous version of the subprocess module会非常有帮助。
我下载了异步子进程并重新编写了脚本以使用它,并使用python -u
来获取无缓冲的I / O:
import async_subprocess as subprocess
cmd = ['python', '-u', 'testfile.py']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
so = p.asyncread()
print so,
(so, se) = p.communicate()
print so
当我使用python -u
运行此脚本时,我得到以下结果:
$ python -u script.py
Line 1 of Text
Input 1:
脚本暂停,等待输入。这是理想的结果。
如果我输入内容(例如“Hullo”),我会得到以下内容:
$ python -u script.py
Line 1 of Text
Input 1:Hullo
Line 2 of Text Input: Hullo
答案 1 :(得分:1)
你真的不需要捕获它的stdout,只需让子程序打印出它的东西并退出,而不是将输出提供给你的父程序并在那里打印。如果您需要变量输出,请改用函数。
但无论如何,那不是你问的。
我实际上从另一个stackoverflow问题得到了这个:
import subprocess, sys
cmd='testfile.py'
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
while True:
out = p.stdout.read(20)
if out == '' and p.poll() != None:
break
if out != '':
sys.stdout.write(out)
sys.stdout.flush()
首先,它会打开您的流程:然后它会不断读取p
的输出并使用sys.stdout.write
将其打印到屏幕上。使这一切工作的部分是sys.stdout.flush()
,它将不断“清除”程序的输出。