2014-02-25 54 views
2

我正在使用python代码启动脚本。此代码应启动在磁盘上写入文件的脚本,然后等待脚本完成。Popen有限缓冲区

但是,无论何时使用python启动此脚本,结果文件不会超过65768字节,并且脚本不再响应。以下是我在python中使用的内容:

p = subprocess.Popen(command, 
        shell=True, 
        stdout=subprocess.PIPE, 
        stderr=subprocess.STDOUT, 
        bufsize=-1) 
p.wait() 

其中command是脚本的命令。

有没有人知道这个问题的解决方案?

谢谢。

+2

该脚本是否也回应(如冗长的东西,如写入文件的副本)到标准输出?事实上,你并没有阅读孩子的标准输出,所以如果它在某个时候变满了,孩子将停止一切(挂在例如'print'语句上),包括写入它的输出文件。 – Tibo

+0

@OneOfOne:它不是重复的。这个问题不是关于'MemoryError';这是由于完整的管道缓冲区造成的死锁。 – jfs

+0

如果你不需要子进程的标准输出,那么你可以将它重定向到devnull:'import os; DEVNULL = open(os.devnull,'wb'); subprocess.check_call([script],stdout = DEVNULL,stderr = STDOUT)' – jfs

回答

0
from time import sleep 
p = subprocess.Popen(command, 
        shell=True, 
        stdout=subprocess.PIPE, 
        stderr=subprocess.STDOUT, 
        bufsize=-1) 
output = '' 
while p.poll() is None: 
    output += p.stdout.readline()+'\n' # <--- This is your magic 
    sleep(0.025) 
output += p.stdout.read() # <--- And this is just to get the leftover data 
print('Command finished') 

p.stdout.close() 

为@ J.F评论上几乎每一个Popen答案我给,你不应该定义stdout=...stdin=...stderr=...,除非你打算utelize他们。 因为他们会填满缓冲区并挂起你的应用程序。

但是,如果你这样做,确保你偶尔“轻点”它。

+0

使用'output = p.communicate()[0]'而不是'output ='''开始的行并且结束。丢弃输出;你可以[使用'DEVNULL'](http://stackoverflow.com/questions/22014648/limited-buffer-in-popen#comment33383993_22014648)。 – jfs

+1

我记得应该用'None'来代替'== None'的评论。 – jfs

+0

@ J.F.Sebastian哈哈哈啊,老兄......老习惯和所有那些..(另外,不要对你的..我不学习,只是有些东西需要一段时间才会落实到快速编码的日常程序中) – Torxed