Python Popen,关闭流和多进程

2024-05-16 07:34:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些数据,我想gzip,uuencode,然后打印到标准输出。我基本上拥有的是:

compressor = Popen("gzip", stdin = subprocess.PIPE, stdout = subprocess.PIPE)
encoder    = Popen(["uuencode", "dummy"], stdin = compressor.stdout)

我把数据输入压缩机的方式是通过压缩机.stdin.write(东西)。在

我真正需要做的是发送一个EOF到压缩机,我不知道怎么做。在

在某种程度上,我试过了压缩机标准关闭()但这不起作用——当压缩器直接写入文件时,它工作得很好,但在上面的情况下,进程不会终止并暂停压缩机。等等(). 在

建议?在本例中,gzip是一个例子,我确实需要做一些事情,将一个进程的输出管道到另一个进程。在

注意:我需要压缩的数据无法放入内存中,因此在这里通信不是一个好的选择。如果我跑的话

^{pr2}$

在上面的2行之后,它仍然挂起错误

  File "/usr/lib/python2.4/subprocess.py", line 1041, in communicate
    rlist, wlist, xlist = select.select(read_set, write_set, [])

Tags: 数据标准进程stdinstdoutselectcompressorwrite
3条回答

这不是您应该直接在python中做的事情,在如何工作方面存在一些古怪之处,这使得使用shell来实现这一点更好。如果你能用子流程.Popen(“foo | bar”,shell=True),那么就更好了。在

可能会发生的情况是gzip还不能输出所有的输入,并且在stdout写入完成之前,进程不会退出。在

如果您使用strace,您可以查看哪个系统称为进程被阻塞。使用ps auxwf来发现哪个进程是gzip进程,然后使用strace -p $pidnum查看它正在执行的系统调用。注意stdin是fd0,stdout是fd1,您可能会看到它在这些文件描述符上读或写。在

我怀疑问题出在你打开管道的顺序上。UUEncode有趣的是,如果没有以正确的方式传入管道,那么当您启动它时,它会发出呜呜声(尝试在Popen调用中单独启动这个该死的东西,以查看只使用管道作为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程序,它的默认行为是期望控制台输入。如果在没有“活动”传入管道的情况下运行它,它将阻止等待控制台输入。第二次打开编码器,在你把材料送到压缩机管道之前,编码器就阻塞了,等着你开始打字。杰鲁布说得对,有什么东西挡住了。在

如果您只想压缩而不需要文件包装器,请考虑使用zlib模块

import zlib
compressed = zlib.compress("text")

shell=True和unix管道建议不起作用的原因是什么?在

^{pr2}$

似乎有用

相关问题 更多 >