Python grep и труба через попен - PullRequest
3 голосов
/ 28 января 2012

Я пытаюсь выполнить поиск в каталоге и ограничить поиск первыми 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 ]

1 голос
/ 28 января 2012

На самом деле в этом случае вы можете сделать:

output = check_output(['/bin/bash', '-c', 'grep -F  "asdasdasd" data/* | head -100'])
0 голосов
/ 01 сентября 2012

Согласно документации Popen о написании каналов вы должны обязательно закрыть stdout на конвейерных процессах (в данном случае p_grep), чтобы они могли получать SIGPIPEот переданных по конвейеру процессов (в данном случае p_head).

Кроме того, согласно этой записи , важно обеспечить функцию настройки для каждого подпроцесса, чтобы 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...