【问题标题】:Execute multiple dependent commands individually with Paramiko and find out when each command finishes使用 Paramiko 单独执行多个依赖命令并找出每个命令何时完成
【发布时间】:2018-11-30 10:18:01
【问题描述】:

我正在用 Python 编写一个程序,它必须通过 SSH 与物理目标通信,并自动向该目标发送一些命令(用于测试)。

我从使用 Paramiko 开始,一切都很完美,直到我必须发送几个命令,例如第二个命令必须在第一个命令的上下文中执行时(例如第一个命令是 cd /mytargetRep,第二个命令是一个是./executeWhatIWant)。我不能使用exec_command 这样做,因为每个exec_command 都会启动一个新会话。

我尝试使用invoke_shell() 的频道,但我有另一个问题:我不知道执行此操作何时结束命令执行。我可以执行一些非常短(及时)的命令,而其他一些则更长,所以我需要知道命令执行何时结束。

我知道将exec_command&& 等shell 逻辑操作一起使用或使用; 的解决方法。例如exec_command("cd /mytargetRep && ./executeWhatIWant")。但我不能那样做,因为它必须也可以手动执行一些命令(我有一个可以发送命令的极简终端),所以例如,用户将创建 cd /mytargetRep 然后 ./executeWhatIWant 而不是 @ 987654332@.

所以我的问题是:有没有解决方案,通过使用 Paramiko 在同一个 SSH 会话中发送多个命令并能够知道命令执行的结束?

谢谢

【问题讨论】:

    标签: python shell ssh command paramiko


    【解决方案1】:

    您似乎想实现一个交互式外壳,但您需要控制单个命令的执行。仅使用 SSH 接口实际上是不可能的。 SSH 中的“shell”通道是带有输入和输出的黑盒。因此,Paramiko 中没有任何东西可以帮助您实现这一点。

    如果您需要了解特定命令何时结束或特定命令的输出在何处结束,则需要使用 shell 的功能。

    您可以通过在两者之间插入一个唯一的分隔符(字符串)并在通道输出流中搜索它来解决这个问题。使用常见的 *nix shell 可以这样工作:

    channel = ssh.invoke_shell()
    channel.send('cd /mytargetRep\n')
    channel.send('echo unique-string-separating-output-of-the-commands\n')
    channel.send('./executeWhatIWant\n')
    

    虽然我真的不认为你经常需要那个。使特定命令正常工作所需的大多数命令,例如 cdset,实际上并不输出任何内容。

    所以在大多数情况下,您可以使用SSHClient.exec_command,您的代码会更简单、更可靠:
    Execute multiple commands in Paramiko so that commands are affected by their predecessors

    即使你需要使用像su/sudo 这样看似复杂的东西,最好还是坚持使用SSHClient.exec_command:
    Executing command using "su -l" in SSH using Python


    对于类似的问题(“exec”频道),请参阅:
    How to get each dependent command execution output using Paramiko exec_command

    【讨论】: