问题描述
有没有办法在 Python Paramiko 中启动一个没有终端仿真的 shell?
Is there a way to start a shell without terminal emulation in Python Paramiko?
- 我曾尝试使用
exec_command
,但我确实需要一个交互式 shell. - 使用
invoke_shell()
我得到一个终端并且可以发出命令,但是从 Windows 10 OpenSSH 服务器我得到一个带有 ANSI 转义序列的输出,包括H
代码,其中不容易处理成纯文本.参考从WIN10 ssh服务器解码数据(paramiko的响应)recv()).
- I have tried using
exec_command
but I really need an interactive shell. - Using
invoke_shell()
I get a terminal and can issue commands, but from Windows 10 OpenSSH server I get an output with ANSI escape sequences, includingH
code, which is not easy to process to plain text. Refer to Decoding data from WIN10 ssh server (response of paramiko recv()).
推荐答案
Paramiko SSHClient.invoke_shell
打开shell"SSH 通道.What 基本上只是执行用户默认 shell 的简写.否则它与什么 SSHexec"通道没有区别(由 SSHClient.exec_command
) 确实如此.
Paramiko SSHClient.invoke_shell
opens "shell" SSH channel. What is basically only a shorthand for executing user's default shell. Otherwise it does not differ to what SSH "exec" channel (used by SSHClient.exec_command
) does.
shell"和exec"SSH 通道都可以在有或没有终端仿真的情况下启动.只是 Paramiko SSHClient.invoke_shell
方法不提供该选项(而 SSHClient.exec_command
通过其 get_pty
参数提供).
Both "shell" and "exec" SSH channels can be started with or without the terminal emulation. It's only that Paramiko SSHClient.invoke_shell
method does not offer that option (while SSHClient.exec_command
does – via its get_pty
parameter).
有两种选择:
使用
SSHClient.exec_channel
显式启动 shell,如
Use
SSHClient.exec_channel
to start the shell explicitly, like
ssh.exec_command("/bin/bash")
在 Linux 服务器上,您甚至可以通过使用 SHELL
环境变量来避免对 shell 路径进行硬编码:
On Linux servers, you may even be able to avoid hard-coding the shell path by using the SHELL
environment variable:
ssh.exec_command("$SHELL")
使用 %CMDSPEC%
(未经测试)在 Windows 上也可以完成类似的操作.
Similar might be done on Windows using %CMDSPEC%
(untested).
或者重新实现 SSHClient.invoke_shell
以支持没有终端仿真的执行.
Or re-implement SSHClient.invoke_shell
to support execution without the terminal emulation.
如果您查看 SSHClient.invoke_shell
实现,它会:
If you look at SSHClient.invoke_shell
implementation, it does:
chan = self._transport.open_session()
chan.get_pty(term, width, height, width_pixels, height_pixels)
chan.invoke_shell()
您只需要做同样的事情,只需删除 Channel.get_pty
调用:
All you need, is to do the same, just remove the Channel.get_pty
call:
chan = ssh.get_transport().open_session()
chan.invoke_shell()
虽然请注意,为什么 SSHClient.invoke_shell
总是使用终端仿真是有原因的.SSHshell"通道的唯一目的是实现交互式 SSH 终端客户端(如 PuTTY).没有终端仿真的终端客户端毫无意义.
Though note that there's a reason, why SSHClient.invoke_shell
always uses the terminal emulation. The only purpose of SSH "shell" channel is implementing an interactive SSH terminal client (like PuTTY). A terminal client without the terminal emulation makes no sense.
如果您想在没有终端仿真的情况下使用shell"通道,这表明您正在滥用它用于非设计目的.如果没有更好的解决方案来解决您正在尝试做的事情,请三思!
这篇关于如何在 Python Paramiko 中启动没有终端仿真的 shell?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!