Входные данные будут поступать из строки, так что на самом деле мне это не нужно echo. Я зашел так далеко, кто-нибудь может объяснить, как я могу передать их по каналу sort тоже?
ОБНОВЛЕНИЕ: Обратите внимание, что, хотя принятый ответ ниже на самом деле не отвечает на заданный вопрос, я считаю, что С. Лотт прав, и лучше вообще не решать эту проблему!
Делегируйте часть работы оболочке. Позвольте ей соединить два процесса конвейером.
Вам было бы намного приятнее переписать 'script.awk' на Python, исключив awk и конвейер.
Редактировать. Некоторые из причин, по которым awk не помогает.
[Слишком много причин для ответа в комментариях.]
Awk добавляет шаг, не имеющий существенного значения. В обработке awk нет ничего уникального, чего не обрабатывал бы Python.
Конвейерная обработка от awk до sort для больших наборов данных может увеличить время обработки. Для коротких наборов данных это не имеет существенного преимущества. Помогает быстрое измерение awk >file ; sort file и awk | sort покажет параллелизм. В случае сортировки это редко помогает, потому что сортировка не является одноразовым фильтром.
Простота обработки "Python для сортировки" (вместо "Python для awk для сортировки") не позволяет задавать здесь вопросы точного типа.
Python - хотя и более словоохотливый, чем awk, - также является явным, где awk имеет определенные неявные правила, которые непрозрачны для новичков и сбивают с толку неспециалистов.
Awk (как и сам сценарий оболочки) добавляет еще один язык программирования. Если все это можно сделать на одном языке (Python), устранение оболочки и программирования awk устраняет два языка программирования, позволяя кому-то сосредоточиться на тех частях задачи, которые создают ценность.
Итог: awk не может добавить значительной ценности. В данном случае awk - это чистая стоимость; это добавило достаточно сложности, чтобы было необходимо задать этот вопрос. Удаление awk будет чистым выигрышем.
Боковая панель Почему построить конвейер (a | b) так сложно.
Когда оболочка сталкивается с a | b, она должна выполнить следующее.
Разветвляйте дочерний процесс исходной оболочки. В конечном итоге это станет b .
Создайте канал операционной системы. (не подпроцесс Python.КАНАЛ), но вызов os.pipe() который возвращает два новых файловых дескриптора, соединенных через общий буфер. На данный момент процесс имеет stdin, stdout, stderr от своего родительского элемента, плюс файл, который будет "a's stdout" и "b's stdin".
Разветвляйте дочерний процесс. Дочерний элемент заменяет свой стандартный вывод на стандартный вывод нового a. Запустите a процесс.
Дочерний элемент b closes заменяет свой stdin на stdin нового b. Запустите процесс b.
Дочерний элемент b ожидает завершения a.
Родительский файл ожидает завершения b.
Я думаю, что приведенное выше можно использовать рекурсивно для создания a | b | c, но вы должны неявно заключать длинные конвейеры в скобки, рассматривая их так, как если бы они были a | (b | c).
Поскольку в Python есть os.pipe(), os.exec() и os.fork(), и вы можете заменить sys.stdin и sys.stdout, есть способ сделать вышеописанное на чистом Python. Действительно, вы можете разработать некоторые быстрые пути, используя os.pipe() и subprocess.Popen.
Однако проще делегировать эту операцию командной оболочке.
#!/usr/bin/env python from subprocess import Popen, PIPE
a = Popen(["a"], stdin=PIPE, stdout=PIPE) with a.stdin: with a.stdout, open("outfile.txt", "wb") as outfile: b = Popen(["b"], stdin=a.stdout, stdout=outfile) a.stdin.write(b"input data") statuses = [a.wait(), b.wait()] # both a.stdin/stdout are closed already
Принятый ответ обходит актуальный вопрос. вот фрагмент, который связывает выходные данные нескольких процессов в цепочку: Обратите внимание, что он также выводит (несколько) эквивалентную команду оболочки, чтобы вы могли запустить ее и убедиться в правильности выходных данных.
print("Output from last process : " + (p3.communicate()[0]).decode())
# thoretically p1 and p2 may still be running, this ensures we are collecting their return codes p1.wait() p2.wait() print("p1 return: ", p1.returncode) print("p2 return: ", p2.returncode) print("p3 return: ", p3.returncode)