我有一个 web.py 应用程序在内置的cherrypy 服务器上运行。我想在用户发布到 url 时执行一个外部脚本,该脚本将在 python 子进程的后台运行。Popen 调用和 web.py 将重定向到另一个页面,在该页面中使用 jquery 监视脚本的进度阿贾克斯请求。但我无法在这里正确实施。代码片段如下,如果需要,我可以提供更多信息。
import web
from multiprocessing import Process
import subprocess, shlex
import time, json
from login import authorize, sessidGen
def __callProcess(processString,mod='w',shell=False):
if not shell: args = shlex.split(processString)
else: args = processString
out = open('./bteq/logs/output.log',mod)
err = open('./bteq/logs/error.log',mod)
p = subprocess.Popen(args,stdout=out,stderr=err,shell=shell)
return p
def setExec():
__callProcess("chmod +x ./bteq/*.sh",shell=True)
def bteqExec(filename,system):
if system not in ['prod','da','cdw','cdw2','cert','']: return False
processString = " ".join([filename,system])
p = __callProcess(processString)
return p.pid
render = web.template.render('templates/',base='layout')
render_plain = web.template.render('templates/')
class Executor:
def GET(self):
authorize()
session = web.ctx.session
inputs = web.input(sessid={},type={})
if not inputs.sessid or session.id != inputs.sessid: web.seeother('/')
if inputs.sessid and inputs.type:
return render.executor('BTEQ Executor',inputs.type,inputs.sessid)
else: raise web.seeother('/')
def POST(self):
authorize()
session = web.ctx.session
inputs = web.input(sessid={},type={},act={})
if not inputs.sessid or session.id != inputs.sessid: web.seeother('/')
if inputs and inputs.act == 'start':
pid = bteqExec('python ./bteq/timer.py','')
session.id = sessidGen()
session.exctrpid = pid
return web.seeother('/progress.htm')
else: raise web.seeother('/')
class progress:
def GET(self):
authorize()
session = web.ctx.session
inputs = web.input(ajax={})
if inputs.ajax == 'true':
web.header('Content-Type', 'application/json')
if session.count >= 100: session.count = 0
session.count += 10
pid = session.exctrpid
out = open('./bteq/logs/output.log','r')
err = open('./bteq/logs/error.log','r')
output = ('<strong>OUTPUT:</strong><br>'+out.read()).replace('\n','<br>')
err = err.read()
if err:error = ('<strong>ERRORS:</strong><br>'+err.read()).replace('\n','<br>')
else: error = None
d = {'count':session.count,'msg':output,'err':error,'rc':pid,'session_id':session.session_id}
return json.dumps(d)
r = web.template.Template('$def with (title)\n$var title: $title\n')
return render_plain.layout_pgbar(r('progress test'))
由于 subprocess.Popen 对象不可腌制,因此无法将其作为会话变量放入,我想从进度类中获取 p.poll() 和 p.stdout.read() 。
此外,我希望代码可在 linux 和 windows 中运行,我在 windows 中设置了我的开发设置,并将其部署在 linux 服务器上。
有人可以在这里帮我吗...
谢谢你。