【问题标题】:Sending commands with Paramiko to BOSCLI shell使用 Paramiko 向 BOSCLI shell 发送命令
【发布时间】:2019-11-12 19:57:42
【问题描述】:

我需要在必须通过 SSH 连接的远程计算机上解析命令的输出。

这台远程机器运行 Ubuntu,我只能通过一个名为 BOSCLI 的“控制台包装器”(抱歉不知道确切的术语)访问 SSH,我只能在其中运行一组特定的命令。 在连接时,我会收到一个输入 sudo 密码的提示,输入后我就在提示下,我不需要再次输入它。

起初我开始使用exec_command,但由于显而易见的原因,它不起作用。我现在切换到invoke_shell(),然后使用send(),但只发送密码提示,而不是以下命令。 当然,我在这里和其他网站上阅读了很多其他问题,但都没有成功...

def conectar(url,user,passw, puerto, sudoPass):
    cliente = paramiko.SSHClient()
    cliente.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    cliente.connect(url,port=puerto, username=user, password=passw)
    if cliente.get_transport() is None: raise Exception(paramiko.SSHException)
    time.sleep(2)
    canal = cliente.invoke_shell()  
    stdin = canal.makefile('wb')
    stdout = canal.makefile('rb')
    stderr = canal.makefile_stderr('r')
    while not canal.recv_ready():
        time.sleep(2)
    aux = canal.send(sudoPass+'\n') #sudo pass 
    out = canal.recv(1024)
    print(aux)
    time.sleep(1)
    aux = canal.send('''dhcp pool status\n''')
    print(aux)

    out += canal.recv(9999)
    #ssh_stdin, ssh_stdout, ssh_stderr = cliente.exec_command('dhcp pool status',get_pty=True)
    #ssh_stdout.channel.recv_exit_status()
    cliente.close()
    print(stdout.read())
    print(stderr.read())
    print(out.decode('ascii'))

输出应该是一个长文本,其中包含不同池上的所有 DHCP 统计信息,以便下一个解析方法,但是我收到的是空输出。

还有一件事现在最让我困惑,那就是实际上“out”有内容(即 shell 上的欢迎 MOTD 等),但 stdout 是空的。

print(aux) returns 9 first  
print(aux) returns 17 afterwards.  
print(stdout.read()) returns b''  
print(stderr.read()) returns b''

out内容如下:

Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.13.0-66-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

  System information as of Tue Jul  2 11:34:22 CEST 2019

  System load:  0.42               Users logged in:        0
  Usage of /:   32.9% of 26.51GB   IP address for eth0:    
  Memory usage: 22%                IP address for eth1:    
  Swap usage:   4%                 IP address for eth2:    
  Processes:    194                IP address for docker0:

  Graph this data and manage this system at:
    https://landscape.canonical.com/

Last login: Tue Jul  
[sudo] password for bos:

(pho-xem1)  (Nuevo)  bcli 0 [] normal>

通过sudo pass后的命令提示符是什么。

【问题讨论】:

  • 你在out得到什么?
  • b'\r\n\r\n(pho-xem1) (Nuevo) bcli 0 [] normal> ' 这是命令提示符。
  • 第一个canal.recv(1024)?
  • 我在问题中添加了print(out.decode('ascii'))的输出
  • 你尝试在aux = canal.send('''dhcp pool status\n''')之后等待吗?

标签: python shell ssh paramiko


【解决方案1】:

您可能在服务器(或实际上是 boscli shell)期望它之前发送命令太早。

您应该等待提示,然后再发送命令。

或者作为一个快速而肮脏的黑客,只需等待一小段时间。


至于stdoutstdout 只是Channel.recv 的包装。由于您已经在使用Channel.recv 中的输出,因此您不会在stdout 中获得更多信息。要么阅读stdout,要么使用Channel.recv,但不能同时使用。

【讨论】:

    相关资源