我想运行一个进程,该进程从python脚本运行无限循环(例如,启动数据库服务器),并捕获stdout和stderr。我尝试了此操作,但是p.communicate()
从未返回,显然是因为该过程需要首先完成。
from subprocess import Popen, PIPE, STDOUT
cmd = "python infinite_loop.py"
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
print("the process is running")
stdout, stderr = p.communicate()
print(stdout)
我想以某种流形式获取输出。例如,我可能想将每100个字符保存到一个新的日志文件中。我该怎么办?
答案 0 :(得分:1)
编辑:与您已经拥有的东西更接近,因为异步似乎对于单个协程来说就显得过分了:
import sys
from subprocess import Popen, PIPE, STDOUT
args = (sys.executable, '-u', 'test4.py')
cmd = ' '.join(args)
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, universal_newlines=True)
print("the process is running")
for line in iter(p.stdout.readline,''):
line = line.rstrip()
print(line)
原始
:我把东西放在一起。下面的示例使用asyncio.subprocess
从子流程的输出中读取行,然后对其进行处理(在这种情况下,仅对它们进行print()
)。
子进程由args
指定,在我的情况下,该子进程仅使用以下脚本(test4.py)以无缓冲模式运行另一个python实例:
import time
for _ in range(10):
print(time.time(), flush=True)
time.sleep(1)
我睡在for
循环中,因此很明显,程序完成后,是单独进入一行还是全部进入一行。 (如果您不相信我,可以将for
循环更改为while True:
,这将永远不会结束)。
“主管”脚本为:
import asyncio.subprocess
import sys
async def get_lines(args):
proc = await asyncio.create_subprocess_exec(*args, stdout=asyncio.subprocess.PIPE)
while proc.returncode is None:
data = await proc.stdout.readline()
if not data: break
line = data.decode('ascii').rstrip()
# Handle line (somehow)
print(line)
if sys.platform == "win32":
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
else:
loop = asyncio.get_event_loop()
args = (sys.executable, '-u', 'test4.py')
loop.run_until_complete(get_lines(args))
loop.close()
请注意,async def
是Python 3.5 +,but you could use @asyncio.coroutine
in 3.4。