一旦有了我需要的数据,如何关闭Python 2.5.2 Popen子进程?

Ale*_*lds 9 python pipe popen

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

$ /usr/bin/env python --version                                                                                                                                                            
Python 2.5.2                                    
Run Code Online (Sandbox Code Playgroud)

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

# 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
Run Code Online (Sandbox Code Playgroud)

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

$ extractMetadata.py | head
Run Code Online (Sandbox Code Playgroud)

如果我输入head,awk,grep等,则会出现错误.

该脚本以以下错误结束:

close failed: [Errno 32] Broken pipe
Run Code Online (Sandbox Code Playgroud)

我本以为关闭管道就足够了,但显然事实并非如此.

Rak*_*kis 4

嗯。我之前见过 subprocess + gzip 的一些“Broken pipeline”奇怪现象。我从来没有弄清楚为什么会发生这种情况,但通过改变我的实现方法,我能够避免这个问题。看起来你只是想使用后端 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)
Run Code Online (Sandbox Code Playgroud)