Получить поток из конвейерного подпроцесса в asyn c с Python - PullRequest
0 голосов
/ 22 марта 2020

Я хотел бы запустить следующие команды непосредственно в Python:

dumpcap -q -f http -i eth0 -w - | tshark -l -n -T json -r - | my_app.py

Я хотел бы запустить его, используя subprocess и asyncio для его запуска в async.

Итак, сначала я хотел бы выполнить:

dumpcap -q -f http -i eth0 -w -

Вывод этой команды должен быть передан в следующую команду, которая должна / может выполняться без синхронизации:

tshark -l -n -T json -r -

Вывод этого должен быть передан в поток, с которым я могу работать.

Есть ли прямое решение для этого?

Ответы [ 2 ]

0 голосов
/ 22 марта 2020

В дополнение к ответу @ user4815162342 обратите внимание, что вы можете просто передать команду полной оболочки в create_subprocess_shell и использовать каналы для связи с обоими концами подпроцесса:

Пример:

proc = await asyncio.create_subprocess_shell(
    "tr a-z A-Z | head -c -2 | tail -c +3",
    stdin=asyncio.subprocess.PIPE,
    stdout=asyncio.subprocess.PIPE,
)
stdout, _ = await proc.communicate(b"**hello**")
assert stdout == b"HELLO"
0 голосов
/ 22 марта 2020

Есть ли прямое решение для этого?

Пример из документации подпроцесса должен также применяться к подпроцессу asyncio. Например (не проверено):

async def process():
    p1 = await asyncio.create_subprocess_shell(
        "dumpcap -q -f http -i eth0 -w -", stdout=asyncio.subprocess.PIPE)
    p2 = await asyncio.create_subprocess_shell(
        "tshark -l -n -T json -r -",
        stdin=p1.stdout, stdout=asyncio.subprocess.PIPE)
    p1.stdout.close()  # we no longer need it

    while True:
        line = await p2.stdout.readline()
        if not line:
            break
        print(line)
...