2008-08-24 50 views

回答

9

如果你正在谈论的Python解释器或cmd.exe,这就是你的脚本的“父”,则没有,这是不可能的。在每一个类似POSIX的系统中(现在你正在运行Windows,看起来,这可能有一些我不知道的怪癖,YMMV),每个进程有三个流,标准输入,标准输出和标准错误。卜默认这些被定向到控制台,但重定向可以使用管道符号(在控制台上运行时):

python script_a.py | python script_b.py 

这关系脚本的标准输出流至脚本B的标准输入流在这个例子中,标准错误仍然在控制台上。请参阅维基百科上关于standard streams的文章。

如果你在谈论一个子进程,你可以从Python启动它,像这样(标准输入也是一种选择,如果你想双向通信):

import subprocess 
# Of course you can open things other than python here :) 
process = subprocess.Popen(["python", "main.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
x = process.stderr.readline() 
y = process.stdout.readline() 
process.wait() 

的信息请参见Python的subprocess模块管理流程。对于通信,process.stdin和process.stdout管道被认为是标准的file objects

对于管道的使用,从标准输入读为lassevk建议你做这样的事情:

import sys 
x = sys.stderr.readline() 
y = sys.stdin.readline() 

sys.stdin和sys.stdout的是标准的文件对象如上所述,在sys定义模块。您可能还想看看pipes模块。

用的ReadLine()作为我的例子中读数据,虽然获取数据的一个非常原始的方法。如果输出不是面向行或不确定的,你可能想看看polling,但不幸的是它不能在Windows中工作,但我确信有一些替代方法。

+1

请注意,使用subprocess.Popen()调用Python时,传递“-u”标志通常会有帮助,该标志禁用stdin/stdout/stderr上的缓冲。当孩子开始读取标准输入时,如果输出已被重定向到管道,Python不会自动刷新标准输出,因此您可以最终阻止永久读取缓冲的输出。我遇到了这个问题,试图包装/自动化pdb。 – 2011-11-18 16:29:49

0

在哪些方面你问?

你们是不是要捕获从你在命令行上启动一个程序的输出?

如果是这样,那么这是如何执行它:

somescript.py | your-capture-program-here 

和读取输出,从标准输入刚才读。

如果,另一方面,你执行该脚本或cmd.exe,或类似从您的程序中,并要等到脚本/程序已完成,并捕获所有的输出,那么你需要看看你用来启动外部程序的库调用,很可能有办法让它给你一些方法来读取输出并等待完成。

1

你想subprocess。在17.1.1中特别注意Popen,并在17.1.2中进行交流。

3

其实,你一定可以,同时它又美又丑又疯了!

您可以用收集输出的StringIO对象替换sys.stdout和sys.stderr。

下面是一个例子,它保存为evil.py:

import sys 
import StringIO 

s = StringIO.StringIO() 

sys.stdout = s 

print "hey, this isn't going to stdout at all!" 
print "where is it ?" 

sys.stderr.write('It actually went to a StringIO object, I will show you now:\n') 
sys.stderr.write(s.getvalue()) 

当你运行这个程序,你会发现:

  • 没事就去到标准输出(其中打印通常版画)
  • 写入stderr的第一个字符串是以'It'开头的字符串
  • 接下来的两行是在StringIO对象中收集的那一行

像这样替换sys.stdout/err是所谓的monkeypatching的应用程序。无论这种“支持”是什么,意见可能会有所不同,它绝对是一种丑陋的黑客攻击,但它在试图环绕外部事物一次或两次时拯救了我的培根。

在Linux上进行测试,而不是在Windows上进行测试,但它应该也能正常工作。让我知道它是否适用于Windows!

4

我想我可以指出你的问题的第一部分的一个很好的答案。

1.    是否有可能从一个Python脚本 捕捉Python解释器的输出?

答案是“”,并亲自我喜欢从PEP 343 -- The "with" Statement文档中的例子下面举。

from contextlib import contextmanager 
import sys 

@contextmanager 
def stdout_redirected(new_stdout): 
    saved_stdout = sys.stdout 
    sys.stdout = new_stdout 
    try: 
     yield None 
    finally: 
     sys.stdout.close() 
     sys.stdout = saved_stdout 

而这样使用的:

with stdout_redirected(open("filename.txt", "w")): 
    print "Hello world" 

它的一个好的方面是,它可以应用于选择性地围绕只是一个脚本的执行的一部分,而不是它的整个范围,并停留在效果即使在其上下文中引发了未处理的异常。如果你第一次使用后,重新打开附加模式的文件,你可以积累的结果到单个文件:

with stdout_redirected(open("filename.txt", "w")): 
    print "Hello world" 

print "screen only output again" 

with stdout_redirected(open("filename.txt", "a")): 
    print "Hello world2" 

当然,上述也可以扩展到也重定向sys.stderr相同或另一个文件。另请参阅此answer相关问题。

相关问题