如何在HTTP请求时使用Python和Flask执行shell命令和流输出?
接下来,我可以如何在HTTP请求时使用Python和Flask执行shell命令和流输出?,python,linux,flask,subprocess,Python,Linux,Flask,Subprocess,接下来,我可以tail-f将日志文件添加到网页: from gevent import sleep from gevent.wsgi import WSGIServer import flask import subprocess app = flask.Flask(__name__) @app.route('/yield') def index(): def inner(): proc = subprocess.Popen( ['ta
tail-f
将日志文件添加到网页:
from gevent import sleep
from gevent.wsgi import WSGIServer
import flask
import subprocess
app = flask.Flask(__name__)
@app.route('/yield')
def index():
def inner():
proc = subprocess.Popen(
['tail -f ./log'],
shell=True,
stdout=subprocess.PIPE
)
for line in iter(proc.stdout.readline,''):
sleep(0.1)
yield line.rstrip() + '<br/>\n'
return flask.Response(inner(), mimetype='text/html')
http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()
从gevent导入睡眠
从gevent.wsgi导入WSGIServer
进口烧瓶
导入子流程
app=烧瓶。烧瓶(\uuuuu名称\uuuuuuu)
@应用程序路径(“/yield”)
def index():
def inner():
proc=子进程Popen(
['tail-f./log'],
shell=True,
stdout=子流程.PIPE
)
对于国际热核实验堆(iter)中的线路(程序标准读线“”):
睡眠(0.1)
屈服线.rstrip()+'
\n'
return flask.Response(inner(),mimetype='text/html')
http_server=WSGIServer(“”,5000),应用程序)
http_server.serve_forever()
这种方法有两个问题
tail-f log
进程将暂停。访问n次后将有n个尾进程tail-f log
之后使用Ctrl+C。如果没有,还有什么选择?
为什么我一次只能有一个客户端访问页面
注意:我正在研究启动/停止任意shell命令的一般方法,而不是特别跟踪文件。一些注意事项:
from gevent.select import select
from gevent.wsgi import WSGIServer
import flask
import subprocess
app = flask.Flask(__name__)
@app.route('/yield')
def index():
def inner():
proc = subprocess.Popen(
['tail -f ./log'],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# pass data until client disconnects, then terminate
# see https://stackoverflow.com/questions/18511119/stop-processing-flask-route-if-request-aborted
try:
awaiting = [proc.stdout, proc.stderr]
while awaiting:
# wait for output on one or more pipes, or for proc to close a pipe
ready, _, _ = select(awaiting, [], [])
for pipe in ready:
line = pipe.readline()
if line:
# some output to report
print "sending line:", line.replace('\n', '\\n')
yield line.rstrip() + '<br/>\n'
else:
# EOF, pipe was closed by proc
awaiting.remove(pipe)
if proc.poll() is None:
print "process closed stdout and stderr but didn't terminate; terminating now."
proc.terminate()
except GeneratorExit:
# occurs when new output is yielded to a disconnected client
print 'client disconnected, killing process'
proc.terminate()
# wait for proc to finish and get return code
ret_code = proc.wait()
print "process return code:", ret_code
return flask.Response(inner(), mimetype='text/html')
http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()
从gevent.select导入选择
从gevent.wsgi导入WSGIServer
进口烧瓶
导入子流程
app=烧瓶。烧瓶(\uuuuu名称\uuuuuuu)
@应用程序路径(“/yield”)
def index():
def inner():
proc=子进程Popen(
['tail-f./log'],
shell=True,
stdout=子流程.PIPE,
stderr=子流程.PIPE
)
#传递数据,直到客户端断开连接,然后终止
#看https://stackoverflow.com/questions/18511119/stop-processing-flask-route-if-request-aborted
尝试:
等待=[proc.stdout,proc.stderr]
等待时:
#等待一个或多个管道上的输出,或等待proc关闭管道
就绪,u,u=选择(等待,[],[])
对于准备就绪的管道:
line=pipe.readline()
如果行:
#要报告的一些输出
打印“发送行:”,行。替换('\n','\\n')
屈服线.rstrip()+'
\n'
其他:
#EOF,管道被proc关闭
等待。移除(管道)
如果proc.poll()为无:
打印“进程已关闭标准输出和标准输出,但未终止;正在终止。”
终止程序()
除发电退出外:
#将新输出提供给断开连接的客户端时发生
打印“客户端断开连接,终止进程”
终止程序()
#等待proc完成并获取返回代码
ret_code=proc.wait()
打印“流程返回代码:”,返回代码
return flask.Response(inner(),mimetype='text/html')
http_server=WSGIServer(“”,5000),应用程序)
http_server.serve_forever()
以下是一些应该完成这项工作的代码。一些注意事项: