提前感谢您的帮助。我对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)
在命令完成后,它会输出整个完成的输出。我还尝试将-u
选项添加到python脚本中以使其无缓冲运行。我也尝试过使用Python subprocess
。如果它有助于我运行的命令类型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()
我没有测试上面的简化示例,因此不确定它的功能是否正确。
编辑:
简化示例现在应该可以使用。
编辑:
如果我打开一个浏览器到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脚本的输出?
答案 0 :(得分:6)
您需要使用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)
这是我们的网络服务器。
# 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()
#!/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'