那么 SSHClient.exec_command()
和在 Paramiko 上使用 SSHClient.invoke_shell
发送有什么区别?
我可以使用 exec_command
向 MikroTik 路由器设备发送和执行命令,但不能使用 send
(invoke_shell()
) 执行它。
另一方面,我可以向 Cisco 设备发送和执行命令 send
(invoke_shell()
),但无法使用 exec_command< 执行它
.
我说的命令是路由(ip route xxx xxx)或者make vlan或者add an ip address等配置命令。
最佳答案
区别在于invoke_shell
使用SSH shell
channel ,而exec_command
使用SSH exec
channel 。
作为用户/开发人员,这对您真正意味着什么取决于 SSH 服务器,而不是 Paramiko 本身。
通用 *nix OpenSSH 服务器:
shell
channel 执行登录 shell(就像您使用 SSH 终端客户端登录一样)。然后 shell 将显示命令提示符并等待客户端/用户键入命令。shell
channel 的目的是实现交互式 shell session 。所以基本上它的合法用途是 SSH 终端客户端的实现。这是一个人很少会做的事情。如果这样做,您通常希望使用 terminal emulation (Paramikoinvoke_shell
无条件地执行此操作,但实际上可以在没有终端仿真的情况下打开shell
channel )。在正常情况下,
shell
channel 显然由 SSH 终端客户端(如 OpenSSHssh
或 PuTTY)使用。shell
channel 是一个带有输入和输出的黑盒子。输入和输出没有结构。例如,如果您通过将命令发送到输入来执行命令,您将永远无法知道它何时结束。如果您将两个命令发送到输入队列,您将无法区分哪个输出来自哪个命令。exec
命令将命令作为“参数”并在隔离环境中执行它 – 仍然通过用户的默认 shell,而不是作为“登录”shell,这可能导致命令执行的显着差异。有关此类差异的典型示例,请参阅 Some Unix commands fail with "<command> not found", when executed using Python Paramiko exec_command .
exec
channel 的目的是自动执行命令。所以通常你不想使用终端仿真,以避免命令做一些花哨的事情,比如分页、着色和主要是交互式确认。这就是get_pty
的默认值为False
的原因。OpenSSH
ssh
或 PuTTYplink
使用exec
channel ,当您指定要在其命令行上执行的命令时:ssh user@host command
对于不太常见的 SSH 服务器,差异可能更加显着。有些服务器甚至可能不支持其中一个 channel 。同样很常见的是,它们似乎同时支持两者,但其中一个(通常是 exec
)已完全损坏。
参见 Executing command using Paramiko exec_command on device is not working .
Java/JSch 也有类似的问题:
What is the difference between the 'shell' channel and the 'exec' channel in JSch
关于python - Paramiko 上的 exec_command 和使用 invoke_shell() 发送有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55762006/