2011-03-24 51 views
2

我试图运行下面的小Python脚本:Python 2.5的subprocess.Popen问题

#!/usr/local/bin/python2.5 
import sys, subprocess 
child = subprocess.Popen("muscle -stable -FASTA", 
         stdin=sys.stdin, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE, 
         shell=(sys.platform!="win32")) 
print child.stderr.read() 
print child.stdout.read() 

如果stdin不超过约3750个字符,工作正常。超过此限制,子流程不再生产任何stdoutstderr。如果我分别将它们切换为sys.stdoutsys.stderr,则所有事情均按预期工作。当从命令行调用时,muscle可执行文件同时写入stdoutstderr

任何建议可能是什么原因以及如何解决这个问题? - 最好不要更新Python,因为安装位于我有限访问的服务器上。

回答

3

使用child.communicate(someinput)得到完整的输出;请参阅文档中的'警告'框。如果你真的需要在写stdout的时候交互地阅读stdin,那么(至少在Windows上)你可能不太会用Python +管道。

+0

谢谢,“out,err = child.communicate()”完美地工作。但为什么我不明白。由于geekosaur解释的原因? – 2011-03-24 23:00:07

+1

@user:'communic'触发两个线程,它们同时读取'stdout'和'stderr'。 http://svn.python.org/view/python/trunk/Lib/subprocess.py?revision=82075&view=markup – 2011-03-24 23:03:13

+0

现在我看到链接并阅读它,是的:-) – 2011-03-24 23:05:19

3

您的进程在完整管道上被阻塞,等待您读取;因为你正在忙着写作,所以你有一个很好的小僵局。如果要同时读取和写入同一个子进程,则应使用基于select()的事件循环,在输出可用时进行读取,并在输入管道中有更多数据存在空间时进行写入。

+1

一个事件循环似乎对我正在尝试做的事情有点矫枉过正。沟通()解决了它,但是无论如何,谢谢。 – 2011-03-24 23:01:15