在此先感谢您的帮助.我是python的新手,甚至更新的HTML.
过去几天我一直在尝试创建一个带有按钮的网页,以便在家庭服务器上执行任务.
目前我有一个python脚本生成一个带按钮的页面:
(See the simplified example below. removed code to clean up post)
然后是一个python脚本,它运行所述命令并输出到页面上的iframe:
(See the simplified example below. removed code to clean up post)
这会在命令完成后输出整个完成的输出.我也尝试在python脚本中添加-u选项以使其无缓冲运行.我也尝试过使用Python子进程.如果它有助于我运行的命令类型是apt-get update,以及其他用于移动文件和修复文件夹权限的Python脚本.
当从普通的Ubuntu服务器终端运行时它运行正常并实时输出,并且从我的研究中它应该在命令运行时输出.
谁能告诉我哪里出错了?我应该使用其他语言来执行此功能吗?
编辑简化示例:
初始页面:
#runcmd.html
<head>
<title>Admin Tasks</title>
</head>
<center>
<iframe src="/scripts/python/test/createbutton.py" width="650" height="800" frameborder="0" ALLOWTRANSPARENCY="true"></iframe>
<iframe width="650" height="800" frameborder="0" ALLOWTRANSPARENCY="true" name="display"></iframe>
</center>
创建按钮的脚本:
cmd_page = '<form action="/scripts/python/test/runcmd.py" method="post" target="display" >' + '<label for="run_update">run updates</label><br>' + '<input align="Left" type="submit" value="runupdate" name="update" title="run_update">' + "</form><br>" + "\n"
print ("Content-type: text/html")
print ''
print cmd_page
应该运行命令的脚本:
# runcmd.py:
import os
import pexpect
import cgi
import cgitb
import sys
cgitb.enable()
fs = cgi.FieldStorage()
sc_command = fs.getvalue("update")
if sc_command == "runupdate":
cmd = "/usr/bin/sudo apt-get update"
pd = pexpect.spawn(cmd, timeout=None, logfile=sys.stdout)
print ("Content-type: text/html")
print ''
print "<pre>"
line = pd.readline()
while line:
line = pd.readline()
我没有测试上面的简化示例,因此不确定它是否具有功能性.
编辑:
简化示例现在应该可以使用.
编辑:
下面的Imrans代码,如果我打开浏览器到ip:8000,它会显示输出,就像它在终端中运行一样,这正是我想要的.除了我使用Apache服务器为我的网站和iframe显示输出.我如何使用Apache做到这一点?
编辑:
我现在使用下面的Imrans示例将输出转到iframe,但它仍然似乎缓冲,例如:
If I have it (the script through the web server using curl ip:8000) run apt-get update in terminal it runs fine but when outputting to the web page it seems to buffer a couple of lines => output => buffer => ouput till the command is done.
But running other python scripts the same way buffer then output everything at once even with the -u flag. While again in terminal running curl ip:800 outputs like normal.
这是应该如何工作的吗?
编辑19-03-2014:
我使用Imrans方式运行的任何bash / shell命令似乎都是近乎实时地输出到iframe.但是,如果我通过它运行任何类型的python脚本,输出将被缓冲,然后发送到iframe.
我是否可能需要PIPE运行Web服务器的脚本运行的python脚本的输出?
解决方法:
您需要使用HTTP chunked transfer encoding来传输无缓冲的命令行输出. CherryPy的wsgiserver模块内置了对分块传输编码的支持. WSGI应用程序可以是返回字符串列表的函数,也可以是生成字符串的生成器.如果您使用生成器作为WSGI应用程序,CherryPy将自动使用分块传输.
我们假设这是程序,其输出将被流式传输.
# slowprint.py
import sys
import time
for i in xrange(5):
print i
sys.stdout.flush()
time.sleep(1)
这是我们的网络服务器.
2014年版(旧版本)
# webserver.py
import subprocess
from cherrypy import wsgiserver
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
proc = subprocess.Popen(['python', 'slowprint.py'], stdout=subprocess.PIPE)
line = proc.stdout.readline()
while line:
yield line
line = proc.stdout.readline()
server = wsgiserver.CherryPyWSGIServer(('0.0.0.0', 8000), application)
server.start()
2018年版
#!/usr/bin/env python2
# webserver.py
import subprocess
import cherrypy
class Root(object):
def index(self):
def content():
proc = subprocess.Popen(['python', 'slowprint.py'], stdout=subprocess.PIPE)
line = proc.stdout.readline()
while line:
yield line
line = proc.stdout.readline()
return content()
index.exposed = True
index._cp_config = {'response.stream': True}
cherrypy.quickstart(Root())
用python webapp.py启动服务器,然后在另一个终端用curl发出请求,并观察输出是否逐行打印
curl 'http://localhost:8000'