Python Flask视图的流式shell输出可以工作,但永远不会结束
我想将几个python3脚本的输出流到我的浏览器中。我从不同的答案中采纳了一些建议,几乎解决了这个问题。但是我从标准输出读取的for循环在执行脚本后会运行到一个无限循环中。输出是正确的,一切都很好,但无休止的循环是一个问题。输出完成后,如何结束流Python Flask视图的流式shell输出可以工作,但永远不会结束,python,flask,stream,Python,Flask,Stream,我想将几个python3脚本的输出流到我的浏览器中。我从不同的答案中采纳了一些建议,几乎解决了这个问题。但是我从标准输出读取的for循环在执行脚本后会运行到一个无限循环中。输出是正确的,一切都很好,但无休止的循环是一个问题。输出完成后,如何结束流 @app.route('/stream/<script>') def execute(script): def inner(): assert re.match(r'^[a-zA-Z._-]+$', script)
@app.route('/stream/<script>')
def execute(script):
def inner():
assert re.match(r'^[a-zA-Z._-]+$', script)
exec_path = "scripts/" + script + ".py"
cmd = ["python3", "-u", exec_path] # -u: don't buffer output
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
)
for line in iter(proc.stdout.readline, ''):
yield highlight(line, BashLexer(), HtmlFormatter())
# If process is done, break loop
# if proc.poll() == 0:
# break
env = Environment(loader=FileSystemLoader('app/templates'))
tmpl = env.get_template('stream.html')
return Response(tmpl.generate(result=inner()))
@app.route(“/stream/”)
def执行(脚本):
def inner():
断言重新匹配(r'^[a-zA-Z.-]+$,脚本)
exec_path=“scripts/”+script+“.py”
cmd=[“python3”,“-u”,exec_path]#-u:不缓冲输出
proc=子进程Popen(
cmd,
stdout=子流程.PIPE,
)
对于iter中的线路(proc.stdout.readline“”):
产生高光(行、BashLexer()、HtmlFormatter())
#若流程完成,则中断循环
#如果proc.poll()==0:
#中断
env=Environment(loader=FileSystemLoader('app/templates'))
tmpl=env.get_模板('stream.html')
返回响应(tmpl.generate(result=internal()))
当我轮询子进程以查看它是否已完成时,脚本的输出会中断,因为当打印速度过快时,它不会打印整个标准输出流。如果在每次打印之间添加sleep(1)
,则不会出现问题
代码可以工作,但运行在无限循环中。如果我取消对这些行的注释,输出会以某种方式被缓冲,部分内容会丢失。我还尝试在单独的线程中轮询子进程,如果不运行,只需切换一个标志,如:break
,但这会导致与上面未注释代码相同的行为。iter(proc.stdout.readline.)
调用readline,直到遇到与'
相等的内容。但是proc.stdout.readline
返回bytes
对象,并且'
是str
对象,因此两者永远不会相等
相反,要么写
for line in iter(proc.stdout.readline, b''):
或者,更好的是:
for line in proc.stdout: