【发布时间】:2015-06-26 17:57:07
【问题描述】:
我基本上想创建一个网页,通过该网页可以访问服务器端的unix终端,可以发送命令并从终端接收结果。
为此,我有一个 WSGIServer。打开连接后,我执行以下操作:
def opened(self):
self.p = Popen(["bash", "-i"], bufsize=1, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
self.p.stdout = Unbuffered(self.p.stdout)
self.t = Thread(target=self.listen_stdout)
self.t.daemon = True
self.t.start()
当消息从客户端到达服务器时,它在以下函数中进行处理,该函数仅将到来的消息重定向到子进程p的标准输入,这是一个交互式bash:
def received_message(self, message):
print(message.data, file=self.p.stdin)
然后在单独的线程t 中的以下函数中读取bash 的输出。它只将输出发送给客户端。
def listen_stdout(self):
while True:
c = self.p.stdout.read(1)
self.send(c)
在这样的系统中,我可以向在服务器端工作的bash 发送任何命令(ls、cd、mkdir 等)并接收它们的输出。但是,当我尝试运行ssh xxx@xxx 时,会显示错误pseudo-terminal will not be allocated because stdin is not a terminal。
另外,以类似的方式,当我运行sudo ... 时,密码提示不会以某种方式发送到客户端,而是出现在服务器脚本的终端上。
我知道expect;但是,仅对于 sudo 和 ssh 这样的用法,我不想将我的代码与 expect 混淆。相反,我正在寻找一种通用的解决方案,可以伪造sudo 和ssh 并将提示重定向到客户端。
有没有办法解决这个问题?想法表示赞赏,谢谢。
【问题讨论】:
-
要么使用
expect,要么使用key-based ssh auth和无密码sudo(危险) -
难道没有任何解决方案可以将所有命令与
sudo和ssh一起运行吗? -
^^ 是的,shell 脚本就是答案。但是,如果某些命令需要通过标准输入进行输入,则必须以某种方式提供它。
expect是一种方式。
标签: python bash ssh terminal client-server