Как я использую подпроцесс. Popen для соединения нескольких процессов каналами?

49
задан twasbrillig 13 November 2014 в 00:07
поделиться

2 ответа

Вы были бы немного более довольны следующим.

import subprocess

awk_sort = subprocess.Popen( "awk -f script.awk | sort > outfile.txt",
    stdin=subprocess.PIPE, shell=True )
awk_sort.communicate( b"input data\n" )

часть Делегата работы к оболочке. Позвольте ему соединить два процесса с конвейером.

Вы были бы намного более счастливой перезаписью 'script.awk' в Python, устранив awk и конвейер.

Редактирование . Некоторые причины предложения, что awk не помогает.

[Существует слишком много причин ответить с помощью комментариев.]

  1. Awk добавляет шаг никакого значительного значения. Нет ничего уникального об обработке awk, которую не обрабатывает Python.

  2. конвейерная обработка от awk до вида, для больших наборов данных, может улучшить истекшее время обработки. Для коротких наборов данных это не обладает никаким значительным преимуществом. Быстрое измерение awk >file ; sort file и awk | sort покажет параллелизма, помогает. С видом это редко помогает, потому что вид не некогда через фильтр.

  3. простота "Python к виду", обрабатывающему (вместо "Python к awk к виду"), предотвращает точный вид вопросов, которые задают здесь.

  4. Python - в то время как более многословный, чем awk - является также явным, где awk имеет определенные неявные правила, которые непрозрачны новичкам, и путающий неспециалистам.

  5. Awk (как сам сценарий оболочки) добавляет еще один Язык программирования. Если все это может быть сделано на одном языке (Python), устранив оболочку, и программирование awk устраняет два языка программирования, позволяя кому-то сфокусироваться на производящих значение частях задачи.

Нижняя строка: awk не может добавить значительное значение. В этом случае awk является сетевой стоимостью; это добавило достаточно сложности, что было необходимо задать этот вопрос. Удаление awk будет чистой прибылью.

Боковая панель , Почему создание конвейера (a | b) так трудно.

, Когда оболочка сталкивается с a | b, она должна сделать следующее.

  1. Разветвляют дочерний процесс исходной оболочки. Это в конечном счете станет b.

  2. Сборка канал OS. (не подпроцесс Python. КАНАЛ), но вызов os.pipe(), который возвращает два новых дескрипторов файлов, которые соединены через общий буфер. В этой точке процесс имеет stdin, stdout, stderr от его родителя, плюс файл, который будет "stdout a" и "stdin b".

  3. Разветвляют ребенка. Ребенок заменяет его stdout stdout нового a. Должностное лицо эти a процесс.

  4. b дочерние завершения заменяет его stdin stdin нового b. Должностное лицо эти b процесс.

  5. b ребенок ожидает для завершения.

  6. родитель ожидает b для завершения.

я думаю, что вышеупомянутое может использоваться рекурсивно для порождения a | b | c, но необходимо неявно заключить длинные конвейеры в скобки, рассматривая их, как будто они a | (b | c).

, Так как Python имеет os.pipe(), os.exec() и os.fork(), и можно заменить sys.stdin и sys.stdout, существует способ сделать вышеупомянутое в чистом Python. Действительно, можно быть в состоянии разработать некоторые ярлыки с помощью [1 115] и subprocess.Popen.

Однако легче делегировать ту операцию к оболочке.

41
ответ дан Adam Spiers 7 November 2019 в 11:40
поделиться

http://www.python.org/doc/2.5.2/lib/node535.html касался этого вполне прилично. Есть ли некоторая часть этого, Вы не поняли?

Ваша программа была бы довольно подобна, но второе Popen будет иметь stdout = в файл, и Вам не был бы нужен вывод .communicate().

3
ответ дан geocar 7 November 2019 в 11:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: