简体   繁体   English

如何在 Python Paramiko 中启动没有终端仿真的 shell?

[英]How do I start a shell without terminal emulation in Python Paramiko?

Is there a way to start a shell without terminal emulation in Python Paramiko?有没有办法在 Python Paramiko 中启动一个没有终端仿真的 shell?

  • I have tried using exec_command but I really need an interactive shell.我试过使用exec_command但我真的需要一个交互式 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, including H code, which is not easy to process to plain text.使用invoke_shell()我得到一个终端并且可以发出命令,但是从 Windows 10 OpenSSH 服务器我得到一个带有 ANSI 转义序列的输出,包括H代码,它不容易处理为纯文本。 Refer to Decoding data from WIN10 ssh server (response of paramiko recv()) .请参阅从 WIN10 ssh 服务器解码数据(paramiko recv() 的响应)

Paramiko SSHClient.invoke_shell opens "shell" SSH channel. SSHClient.invoke_shell打开“shell”SSH 通道。 What is basically only a shorthand for executing user's default shell. What 基本上只是执行用户默认 shell 的简写。 Otherwise it does not differ to what SSH "exec" channel (used by SSHClient.exec_command ) does.否则它与 SSH“exec”通道(由SSHClient.exec_command )的作用没有SSHClient.exec_command

Both "shell" and "exec" SSH channels can be started with or without the terminal emulation. “shell”和“exec”SSH 通道都可以在有或没有终端仿真的情况下启动。 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.invoke_shell方法不提供该选项(而SSHClient.exec_command提供 - 通过其get_pty参数)。

There are two alternatives:有两种选择:

  • Use SSHClient.exec_channel to start the shell explicitly, like使用SSHClient.exec_channel显式启动 shell,例如

    ssh.exec_command("/bin/bash")

    On Linux servers, you may even be able to avoid hard-coding the shell path by using the SHELL environment variable:在 Linux 服务器上,您甚至可以通过使用SHELL环境变量来避免对 shell 路径进行硬编码:

     ssh.exec_command("$SHELL")

    Similar might be done on Windows using %CMDSPEC% (untested).使用%CMDSPEC% (未经测试)在 Windows 上也可以完成类似的操作。

  • 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:如果您查看SSHClient.invoke_shell实现,它会:

     chan = self._transport.open_session() chan.get_pty(term, width, height, width_pixels, height_pixels) chan.invoke_shell()

    All you need, is to do the same, just remove the Channel.get_pty call:您所需要的只是做同样的事情,只需删除Channel.get_pty调用:

     chan = ssh.get_transport().open_session() chan.invoke_shell()

Though note that there's a reason, why SSHClient.invoke_shell always uses the terminal emulation.虽然请注意这是有原因的,为什么SSHClient.invoke_shell总是使用终端仿真。 The only purpose of SSH "shell" channel is implementing an interactive SSH terminal client (like PuTTY). SSH“shell”通道的唯一目的是实现交互式 SSH 终端客户端(如 PuTTY)。 A terminal client without the terminal emulation makes no sense.没有终端仿真的终端客户端毫无意义。

That you want to use "shell" channel without the terminal emulation indicates, that you are abusing it for purposes for which it was not designed.您想在没有终端仿真的情况下使用“shell”通道表明您正在将其滥用于非设计目的。 Think twice, if there's not a better solution to what you are trying to do!如果没有更好的解决方案来解决您正在尝试做的事情,请三思!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM