exec_command 和在 Paramiko 上用 invoke_shell() 发送有什么区别?

What is the difference between exec_command and send with invoke_shell() on Paramiko?

那么 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 ip address等配置命令。

区别在于invoke_shell使用SSHshell通道,而exec_command使用SSHexec通道。

作为 user/developer,这对您来说真正意味着什么,实际上取决于 SSH 服务器,而不是 Paramiko 本身。


常见的 *nix OpenSSH 服务器:

  • shell 通道执行登录shell(就像您使用 SSH 终端客户端登录一样)。然后 shell 将显示命令提示符并等待 client/user 键入命令。 shell 频道的目的是实现交互式 shell 会话。所以基本上它的合法用途是 SSH 终端客户端的实现。这是一个人很少会做的事情。如果这样做,您通常希望使用 terminal emulation(Paramiko invoke_shell 无条件地这样做,但实际上可以在没有终端仿真的情况下打开 shell 通道)。

    正常情况下,shell 通道显然由 SSH 终端客户端(如 OpenSSH ssh 或 PuTTY)使用。

    shell 通道是一个带有输入和输出的黑盒子。输入和输出没有结构。例如,如果您通过将命令发送到输入来执行命令,您将永远无法知道它何时结束。如果你向输入队列发送两个命令,你将无法区分哪个输出来自哪个命令。

  • exec 命令将命令作为“参数”并在隔离环境中执行它 – 仍然通过用户的默认设置 shell,但不是作为“登录” shell,什么可能导致命令执行出现显着差异。

    有关此类差异的典型示例,请参阅

    exec 通道的目的是自动执行命令。所以通常你不想使用终端仿真,以避免命令做一些花哨的事情,比如分页、着色和主要是交互式确认。这就是为什么 get_pty 的默认值是 False.

    当您指定要在其命令行上执行的命令时,OpenSSH ssh 或 PuTTY plink 使用 exec 通道:

    ssh user@host command
    

对于不太常见的 SSH 服务器,差异可能更加显着。有些服务器甚至可能不支持其中一个频道。它们似乎同时支持两者也是很常见的,但其中一个(通常是 exec)已完全损坏。

参见


Java/JSch也有类似的问题:
What is the difference between the 'shell' channel and the 'exec' channel in JSch