Python grep和管道通过Popen

时间:2012-01-27 21:44:17

标签: python subprocess

我正在尝试从目录中grep并将搜索限制为前100个结果。以下代码继续产生

[..]
grep: writing output: Broken pipe
grep: writing output: Broken pipe
grep: writing output: Broken pipe
grep: writing output: Broken pipe
[..]

代码:

p_grep = Popen(['/bin/bash', '-c', 'grep -F  "asdasdasd" data/*'], stdout = PIPE)
p_head = Popen(['head', '-100'], stdin = p_grep.stdout, stdout = PIPE)
output = p_head.communicate()[0]

如何解决?

2 个答案:

答案 0 :(得分:1)

实际上在这种情况下你可以这样做:

output = check_output(['/bin/bash', '-c', 'grep -F  "asdasdasd" data/* | head -100'])

答案 1 :(得分:0)

根据Popen documentation on writing pipes,您应该确保关闭管道流程上的stdout(在这种情况下为p_grep),以便他们能够收到SIGPIPE从管道到流程(在这种情况下为p_head)。

此外,根据this post,为每个子进程提供一个设置函数非常重要,这样Python对SIGPIPE的处理就会恢复为默认行为。

所以代码变成:

def preexec_fn():
    import signal
    signal.signal(signal.SIGPIPE, signal.SIG_DFL)

p_grep = Popen(['/bin/bash', '-c', 'grep -F  "asdasdasd" data/*'], stdout=PIPE, preexec_fn=preexec_fn)
p_head = Popen(['head', '-100'], stdin=p_grep.stdout, stdout=PIPE, preexec_fn=preexec_fn)
p_grep.stdout.close()
output = p_head.communicate()[0]

这应该导致grep进程在head完成后终止。