使用python中的代码模块重定向stdin的输出?

时间:2014-03-15 15:06:15

标签: python subprocess pipe stdin

我正试图找出一种方法来重定向我编写的运行交互式控制台的脚本的输出。

我需要能够:

  

捕获字符串中的输出,然后   检查,或打印出来。

这可行吗?我应该使用不同的python模块吗?

我尝试使用subprocess模块,但遇到了一个问题,我只能在流程结束时进行1次读取。这不会起作用,我需要多次从stdout读取。这就是我到目前为止所做的:

import code
console = code.InteractiveConsole()
console.push('from sim import newsteam\n')
console.push('assembler = newsteam()\n')
console.push('assembler.__init__()\n')

line = console.push('assembler.reportr()\n')
#I need to be able to interact with this output
line1 = console.push('assembler.reportpc()\n')
line2 = console.push('assembler.reportm()\n')

print("this is the result: " + line + line1 + line2)

4 个答案:

答案 0 :(得分:1)

您可以暂时重定向stdout:

import code
import sys
from contextlib import contextmanager

try:
    from StringIO import StringIO
except ImportError: # Python 3
    from io import StringIO

try:
    from contextlib import redirect_stdout 
except ImportError: # Python < 3.4
    @contextmanager
    def redirect_stdout(new_target):
        old_target, sys.stdout = sys.stdout, new_target # replace sys.stdout
        try:
            yield new_target # run some code with the replaced stdout
        finally:
            sys.stdout = old_target # restore to the previous value

f = StringIO()
with redirect_stdout(f):
    console = code.InteractiveConsole()
    console.push('print("hello world")')
    console.push('i = int(input("give me a number"))')
    console.push('sq = i*i')
    console.push('print("%d squared is %d" % (i, sq))')
print("Got: %r" % f.getvalue())

示例:

$ echo 2 | python code-interactive.py 
Got: 'hello world\ngive me a number2 squared is 4\n'

答案 1 :(得分:0)

也许您可以尝试使用子进程Popen,将IDLE作为子进程生成,并使用管道手动处理stdin和stdout。但是,如果您按照该路线阅读非阻塞读/写的解决方案。默认情况下,读取(即readlines())将继续读取,直到子进程结束。看起来你需要它是交互式的(处理stdin和stdout)。查看this thread

答案 2 :(得分:0)

pop = subprocess.Popen([ "command",'argument'] , stdin=subprocess.PIPE , stdout =subprocess.PIPE  )  
while True:
    l = pop.stdout.readline()
    if not l :
        break 
    if l == '':
        time.sleep(1)
        continue 
    # do some function with l 
    # ....

N.B :.没有经过测试,但应该可以使用。

感谢@ J.F. Sebastian_comment

答案 3 :(得分:0)

您可以使用局部变量来存储控制台内生成的结果。

例如:

import code
output = []
console = code.InteractiveConsole({'output':output})
console.push('import sys')
line = console.push('output.append(sys.version)')
print('Result value:', output)

您将获得一个列表,其中包含您要在主模块中检查的输出行。

在您的情况下,您可以执行以下操作:

import code
output = []
console = code.InteractiveConsole({'output': output})
console.push('from sim import newsteam\n')
console.push('assembler = newsteam()\n')
console.push('assembler.__init__()\n')

console.push('output.append(assembler.reportr())')
console.push('output.append(assembler.reportpc())')
console.push('output.append(assembler.reportm())')

print("this is the result: ", output)