我有一些数据想要 gzip、uuencode 然后打印到标准输出。我基本上拥有的是:
compressor = Popen("gzip", stdin = subprocess.PIPE, stdout = subprocess.PIPE)
encoder = Popen(["uuencode", "dummy"], stdin = compressor.stdout)
我向压缩器提供数据的方式是通过 compressor.stdin.write(stuff)。
我真正需要做的是向压缩器发送一个 EOF,但我不知道该怎么做。
在某些时候,我尝试了 compressor.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 作为 stdin 和 stdout 来查看爆炸)
试试这个:
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(24TL3@4`;2O+"!(`````
`
end
你是对的,顺便说一句......没有办法通过管道发送一个通用的 EOF。毕竟,每个程序都真正定义了自己的 EOF。方法是关闭管道,就像您尝试做的那样。
编辑:我应该更清楚 uuencode。作为一个 shell 程序,它的默认行为是期待控制台输入。如果您在没有“实时”传入管道的情况下运行它,它将阻塞等待控制台输入。通过第二次打开编码器,在您将 Material 发送到压缩机管道之前,编码器会阻塞等待您开始输入。耶鲁布是对的,因为有东西阻挡了。
关于Python Popen,关闭流和多进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/617308/