Python Popen,关闭流和多个进程
我有一些数据,我想gzip,uuencode,然后打印到标准输出。我基本上有:Python Popen,关闭流和多个进程
compressor = Popen("gzip", stdin = subprocess.PIPE, stdout = subprocess.PIPE)
encoder = Popen(["uuencode", "dummy"], stdin = compressor.stdout)
我给压缩机提供数据的方式是通过compressor.stdin.write(东西)。
我真的需要做的是发送一个EOF到压缩机,我不知道该怎么做。
在某些时候,我尝试了压缩机.stdin.close(),但不起作用 - 它压缩机直接写入文件时效果很好,但在上述情况下,过程不会终止并且在compressor.wait()上停顿。
对此提出建议?在这种情况下,gzip就是一个例子,我真的需要将一个进程的输出管道连接到另一个进程。
注:我需要压缩的数据不适合内存,所以在这里沟通并不是一个好的选择。另外,如果我只是运行
compressor.communicate("Testing")
上面的两行之后
,它仍然与错误
File "/usr/lib/python2.4/subprocess.py", line 1041, in communicate rlist, wlist, xlist = select.select(read_set, write_set, [])
我怀疑问题出在您打开管道的顺序。 UUEncode很有意思的是,如果没有正确的输入管道,它会发出呜呜声(尝试在Popen调用中自行启动补丁程序,以PIPE作为标准输入和标准输出来看爆炸)
试试这个:
encoder = Popen(["uuencode", "dummy"], stdin=PIPE, stdout=PIPE)
compressor = Popen("gzip", stdin=PIPE, stdout=encoder.stdin)
compressor.communicate("UUencode me please")
encoded_text = encoder.communicate()[0]
print encoded_text
begin 644 dummy
F'XL(`%]^L$D``PL-3<U+SD])5<A-52C([email protected]`;2O+"!(`````
`
end
你是对的,顺便说一句...有没有办法发送通用EOF下来的管道。毕竟,每个程序都确实定义了自己的EOF。要做到这一点的方法是关闭管道,就像你试图做的那样。
编辑:我应该更清楚uuencode。作为一个shell程序,它的默认行为是期望控制台输入。如果您在没有“实时”传入管道的情况下运行它,它将阻止等待控制台输入。第二次打开编码器,在压缩机管道下传送材料之前,编码器阻止了您等待您开始输入。耶鲁是对的,因为有阻碍。
不幸的是,它仍然需要将整个输出存储在内存中,如果您尝试读取()编码器stdout它似乎仍然挂起 – cobbal 2009-03-06 01:48:08
,如果你只是想压缩和不需要的文件封装挂起考虑使用zlib模块
import zlib
compressed = zlib.compress("text")
什么原因为什么shell = True和unix管道建议不起作用?
from subprocess import *
pipes = Popen("gzip | uuencode dummy", stdin=PIPE, stdout=PIPE, shell=True)
for i in range(1, 100):
pipes.stdin.write("some data")
pipes.stdin.close()
print pipes.stdout.read()
似乎工作
这不是之类的事情,你应该直接在Python做,有关于事物是如何工作的怪癖,使其成为一个更好的主意了壳里做这个。如果你可以使用subprocess.Popen(“foo | bar”,shell = True),那么一切都会好一些。
可能发生的情况是,gzip尚未能够输出其所有输入,并且在stdout写入完成之前,该进程将不会退出。
如果你使用strace,你可以看看哪些系统调用过程被阻塞。使用ps auxwf
来发现哪个进程是gzip进程,然后使用strace -p $pidnum
来查看它正在执行的系统调用。请注意,标准输入为FD 0,标准输出为FD 1,您可能会看到它读取或写入这些文件描述符。
尽管cobbal的答案将适用于gzip,但这实际上只是一个例子 - 我确实需要管道... – bsdfish 2009-03-06 00:36:33