2016-05-20 2 views
0

Вот тестовый файл:процесса Python трубы с subprocess.Popen

gunzip -c file_1.gz 
Line 1 
Line 2 
Line 3 

Я выполнения Баш команды таким образом:

cmd = "gunzip -c file_1.gz | grep 3" 
subprocess.call(cmd, shell=True)) 
Line 3 

Мне нужно запустить эту команду на несколько файлов параллельно, затем присоединитесь к процессам. Я думаю, мне нужно использовать subprocess.Popen().communicate(). Однако Popen не будет правильно распознать трубу и будет кормить его к первой команде, разархивировать в моем случае:

subprocess.Popen(cmd.split()).communicate()) 
gunzip: can't stat: | (|.gz): No such file or directory 
gunzip: can't stat: grep (grep.gz): No such file or directory 
gunzip: can't stat: 8 (8.gz): No such file or directory 

Я хотел бы сохранить всю команду и избежать разделения его таким образом:

gunzip = subprocess.Popen('gunzip -c file_1.gz'.split(), stdout=subprocess.PIPE) 
grep = subprocess.Popen('grep 3'.split(), stdin=gunzip.stdout, stdout=subprocess.PIPE) 
gunzip.stdout.close() 
output = grep.communicate()[0] 
gunzip.wait() 

Есть ли способ не отделять команды и обрабатывать трубу правильно?

+1

Что означает «присоединиться к процессам»? Вы хотите захватить вывод нескольких процессов, работающих одновременно? Вот [пример кода] (http://stackoverflow.com/a/23616229/4279). Несвязанный: ваш код, вероятно, связан с IO, т. Е. Не может быть смысла читать файлы параллельно, если они уже не находятся в памяти. – jfs

+0

Извините за задержку .. Присоединившись к процессам, я ожидаю, пока все grep не будут завершены в каждом файле. Ваш ответ, о котором вы говорите, примечателен! – kaligne

ответ

1

Для выполнения команды grep 3 вам нужен вывод из предыдущей команды, поэтому нет возможности успешно запустить эту команду в одной команде с помощью subprocess.Popen.

Если вы всегда хотите запустить grep 3 для всех файлов, вы можете просто присоединиться к результатам всего gunzip -c file_x.gz, а затем запустить команду grep только один раз во всем списке.

subprocess.Popen('gunzip -c file_1.gz'.split(), stdout=subprocess.PIPE) 
subprocess.Popen('gunzip -c file_2.gz'.split(), stdout=subprocess.PIPE) 
... 
grep = subprocess.Popen('grep 3'.split(), stdin=all_gunzip_stdout, stdout=subprocess.PIPE) 
Смежные вопросы