让stdout显示名为包含输入的脚本

时间:2012-03-30 03:35:03

标签: python subprocess stdout

我正在寻找一个调用另一个脚本并捕获其标准输出的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在被调用脚本仍在运行时打印?

谢谢,

2 个答案:

答案 0 :(得分:3)

这里有两个问题。

  1. 首先,python将输出缓冲到stdout,你需要阻止它。您可以像{I} Frenkel建议的那样在sys.stdout.flush()中插入对testfile.py的调用,或者您可以使用python -u执行带有无缓冲I / O的testfile.py。 (参见Ilia链接的other stack overflow question。)

  2. 您需要一种从子流程异步读取数据的方法,然后在准备好输入时,打印您读取的数据,以便显示用户的提示。为此,拥有asynchronous version of the subprocess module会非常有帮助。

  3. 我下载了异步子进程并重新编写了脚本以使用它,并使用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(),它将不断“清除”程序的输出。