以与Python异步的方式从管道子流程获取流

以与Python异步的方式从管道子流程获取流,python,python-3.x,subprocess,python-asyncio,Python,Python 3.x,Subprocess,Python Asyncio,我想直接在Python中运行以下命令: dumpcap -q -f http -i eth0 -w - | tshark -l -n -T json -r - | my_app.py 我想通过使用子流程和asyncio来运行它,以便在async中运行它 因此,首先我想运行: dumpcap -q -f http -i eth0 -w - 此命令的输出应通过管道传输到下一个命令,该命令应/可能不同步运行: tshark -l -n -T json -r - 这个输出应该通过管道传输到我可以使

我想直接在
Python
中运行以下命令:

dumpcap -q -f http -i eth0 -w - | tshark -l -n -T json -r - | my_app.py
我想通过使用
子流程
asyncio
来运行它,以便在
async
中运行它

因此,首先我想运行:

dumpcap -q -f http -i eth0 -w -
此命令的输出应通过管道传输到下一个命令,该命令应/可能不同步运行:

tshark -l -n -T json -r -
这个输出应该通过管道传输到我可以使用的流中

有没有一个简单的解决方案

有没有一个简单的解决方案

子流程文档中的说明也应适用于异步IO子流程。例如(未经测试):

async def process():
p1=等待asyncio.create_subprocess_shell(
“dumpcap-q-f http-i eth0-w-”,stdout=asyncio.subprocess.PIPE)
p2=等待asyncio.create_subprocess_shell(
“tshark-l-n-tjson-r-”,
stdin=p1.stdout,stdout=asyncio.subprocess.PIPE)
p1.stdout.close()#我们不再需要它了
尽管如此:
line=wait p2.stdout.readline()
如果不是直线:
打破
打印(行)

除了@user4815162342的答案之外,请注意,您只需将完整的shell命令传递给子流程,并使用管道与子流程的两端进行通信:

例如:

proc=wait asyncio.create\u subprocess\u shell(
“tr a-z a-z |头-c-2 |尾-c+3”,
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
)
stdout,等待程序通信(b“**你好**”)
断言stdout==b“HELLO”

addfirst我得到了
无效语法
,因此更改为放入
async def run():您的代码
,然后使用
asyncio.run(run())
运行。现在,我在冒号
@AlfredBalle处得到了行
无效语法
…行:=wait p2.stdout.readline…
,您需要Python3.8来实现,您可能使用的是3.7或更早版本。我现在修改了代码,不使用它,并添加了一个显式的
async def
proc.communicate()
将尝试读取所有数据,而不是逐行流式传输。这不利于内存使用(想象一下,如果您期望子标准输出大于主RAM),也不利于性能(在子标准输出完成之前,不会处理第一行)@inetknght当然,这确实取决于正在运行的命令。例如,
communicate()
如果命令已经包含一些聚合并产生一个小的输出(例如
tail-n1
wc
,等等),则可以使用
communicate()。