python - 获得所需数据后,如何关闭 Python 2.5.2 Popen 子进程?

标签 python pipe popen

我正在运行以下版本的 Python:

$ /usr/bin/env python --version                                                                                                                                                            
Python 2.5.2                                    

我正在运行以下 Python 代码,将子进程中的数据写入标准输出,并将其读入名为 metadata 的 Python 变量:

# Extract metadata (snippet from extractMetadata.py)
inFileAsGzip = "%s.gz" % inFile                                                                                                                                                                                                            
if os.path.exists(inFileAsGzip):                                                                                                                                                                                                           
    os.remove(inFileAsGzip)                                                                                                                                                                                                                
os.symlink(inFile, inFileAsGzip)                                                                                                                                                                                                           
extractMetadataCommand = "bgzip -c -d -b 0 -s %s %s" % (metadataRequiredFileSize, inFileAsGzip)                                                                                                                                            
metadataPipes = subprocess.Popen(extractMetadataCommand, stdin=None, stdout=subprocess.PIPE, shell=True, close_fds=True)                                                                                                      
metadata = metadataPipes.communicate()[0]                                                                                                                                                                                                                                                                                                                                                                                                          
metadataPipes.stdout.close()                                                                                                                                                                                                             
os.remove(inFileAsGzip) 
print metadata

用例如下,从上述代码片段中提取前十行标准输出:

$ extractMetadata.py | head

如果我通过管道输入 head、awk、grep 等,就会出现错误。

脚本以以下错误结束:

close failed: [Errno 32] Broken pipe

我原以为关闭管道就足够了,但显然情况并非如此。

最佳答案

嗯。我之前已经看到 subprocess + gzip 有一些“破管”的奇怪之处。我从来没有弄清楚为什么会这样,但是通过改变我的实现方法,我能够避免这个问题。看起来您只是在尝试使用后端 gzip 进程来解压缩文件(可能是因为 Python 的内置模块非常慢……不知道为什么,但确实如此)。

您可以不使用 communicate(),而是将进程视为完全异步的后端,并在输出到达时读取它。当流程结束时,子流程模块会为您清理一切。以下代码片段应提供相同的基本功能,而不会出现任何损坏的管道问题。

import subprocess

gz_proc = subprocess.Popen(['gzip', '-c', '-d', 'test.gz'], stdout=subprocess.PIPE)

l = list()
while True:
    dat = gz_proc.stdout.read(4096)
    if not d:
        break
    l.append(d)

file_data = ''.join(l)

关于python - 获得所需数据后,如何关闭 Python 2.5.2 Popen 子进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3861087/

相关文章:

python - 为 pysqlite3 数据库创建类似 "less"的控制台寻呼机界面

javascript - 如何使用 Node.js createReadStream 和 createWriteStream 写入多个文件

python - 从 python 运行 vssadmin

python - 继承或模拟 pythons etree.ElementTree.Element 可能吗?

python - 用python计算字母

c - 管道和过程管理

c - 使用 libavformat 比使用 popen 调用 ffmpeg 更快吗?

c - popen 创建一个额外的 sh 进程

python - Pandas 中的累积总和从零开始,以除最后一个条目以外的所有组的总和结束

c - 导航功能将其所有输出打印两次