我正在使用 Python + Flask 开发网络应用程序。从最简单的意义上讲,客户端对特定 URL 的请求将触发应用程序登录到服务器端的远程机器,执行一系列 shell 命令,并将输出(JSON 格式)解析并发送给客户端作为响应的一部分。这些命令相当简单。要登录到远程机器,我唯一可用的方法是 rlogin,所以我使用了 pexpect 模块,因为我 couldn't find rlogin 的任何标准 Python 模块。
现在的问题是,虽然我能够从 pexpect/rlogin 获得正确的输出,但将该输出(字符串)作为响应发送会导致错误:
----------------------------------------
Exception happened during processing of request from ('171.71.55.54', 62736)
Traceback (most recent call last):
File "/isan/python/python2.7/SocketServer.py", line 295, in _handle_request_noblock
self.process_request(request, client_address)
File "/isan/python/python2.7/SocketServer.py", line 321, in process_request
self.finish_request(request, client_address)
File "/isan/python/python2.7/SocketServer.py", line 334, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/isan/python/python2.7/SocketServer.py", line 651, in __init__
self.finish()
File "/isan/python/python2.7/SocketServer.py", line 710, in finish
self.wfile.close()
File "/isan/python/python2.7/socket.py", line 279, in close
self.flush()
File "/isan/python/python2.7/socket.py", line 303, in flush
self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 9] Bad file descriptor
----------------------------------------
我已将代码精简到重现错误所需的最低限度。对此应用程序的 HTTP 请求导致“文件描述符错误”错误。抱歉缩进不同,我使用了两个不同的编辑器来修改代码!
import os
import subprocess
import pexpect
from flask import Flask
app = Flask(__name__)
class rlogin:
def __init__(self, host, prompt):
self.child = pexpect.spawn("rlogin " + host)
self.prompt = prompt
self.child.expect_exact(self.prompt)
def command(self, command):
self.child.sendline(command)
self.child.expect_exact(self.prompt)
response = self.child.before
return response
def close(self):
self.child.close()
@app.route('/')
def index():
rl = rlogin("myserver", "root@myserver:~# ")
output = rl.command("pwd")
rl.close()
# The output of the next line is just as I expect:
print output
# This is probably where it fails:
return output
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
删除对 rlogin()
、rl.command()
和 rl.close()
的调用,并返回一个简单的字符串,例如“A”解决了错误。我已经在这个问题上停留了一段时间,非常感谢任何帮助。谢谢!
最佳答案
您必须确保返回类型是 str、unicode、响应类或 WSGI 函数。看起来您的输出不属于任何可接受的 Flask 路由返回类型。
@app.route('/')
def index():
rl = rlogin("myserver", "...")
output = rl.command("pwd")
rl.close()
print type(output)
# Convert output into something that flask can understand
value = str(output)
resp = make_response(value)
resp.headers['Content-Type'] = 'text/plain'
return resp
您可以在 http://flask.pocoo.org/docs/0.10/api/#flask.Flask.make_response 阅读更多相关信息
关于Python + Flask 网络应用报告 "[Errno 9] Bad file descriptor"与 pexpect 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31306725/