【问题标题】:Paramiko exec_command with multiple commands on Cisco router not providing any outputParamiko exec_command 与 Cisco 路由器上的多个命令不提供任何输出
【发布时间】:2018-06-22 02:07:11
【问题描述】:
login_user = 'xyz'
login_pass = 'xyz'
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(device, username=login_user, password=login_pass, look_for_keys=False, timeout=5)
print "success loggedin"
stdin, stdout, stderr = ssh.exec_command("term len 0 ; show int desc | i Tu ; show ip interface brief | in Tunnel ; show ip bgp vpnv4 vrf AWS summary | i 169.25 ; show ip route vrf AWS bgp")
all_output = stdout.read()
print all_output

上面是我的代码 sn-p,只传递一个命令就可以很好地打印结果,但是使用上面的多个命令,它不起作用(没有输出)。登录的设备是 Cisco ASR1006 - 它与设备有什么关系吗?

非常感谢任何帮助!


由于多个命令不起作用,我将下面的代码与多个 exec_command 一起使用,但这每次执行大约需要 30-40 秒。 每个命令执行都需要 ssh.connect 吗?

ssh.connect(device, username=login_user, password=login_pass, look_for_keys=False)
stdin, stdout, stderr = ssh.exec_command('show int desc | i Tu')
vpc_ints = stdout.read()
ssh.connect(device, username=login_user, password=login_pass, look_for_keys=False)
stdin, stdout, stderr = ssh.exec_command('show ip interface brief | in Tunnel')
vpc_peers = stdout.read()
ssh.connect(device, username=login_user, password=login_pass, look_for_keys=False)
stdin, stdout, stderr = ssh.exec_command('show ip bgp vpnv4 vrf AWS summary | i 169.25')
vpc_bgp_routes = stdout.read()
ssh.connect(device, username=login_user, password=login_pass, look_for_keys=False)
stdin, stdout, stderr = ssh.exec_command('show ip route vrf AWS bgp')
ip_routes_list = stdout.read()

按照 cmets 中的建议,我还尝试通过一个连接多次调用 exec_command

ssh.connect(device, username=login_user, password=login_pass, look_for_keys=False)
stdin, stdout, stderr = ssh.exec_command('show int desc | i Tu')
vpc_ints = stdout.read()
#ssh.connect(device, username=login_user, password=login_pass, look_for_keys=False)
stdin, stdout, stderr = ssh.exec_command('show ip interface brief | in Tunnel')
vpc_peers = stdout.read()
#ssh.connect(device, username=login_user, password=login_pass, look_for_keys=False)
stdin, stdout, stderr = ssh.exec_command('show ip bgp vpnv4 vrf AWS summary | i 169.25')
vpc_bgp_routes = stdout.read()
#ssh.connect(device, username=login_user, password=login_pass, look_for_keys=False)
stdin, stdout, stderr = ssh.exec_command('show ip route vrf AWS bgp')
ip_routes_list = stdout.read()
ssh.close()

但这失败了:

File "C:\Python27\myvpndashboard\myvpnapp\tunnel_summary.py", line 179, in dataset_build
cisco_show(device)
File "C:\Python27\myvpndashboard\myvpnapp\tunnel_summary.py", line 36, in cisco_show
stdin, stdout, stderr = ssh.exec_command('show ip interface brief | in Tunnel')
File "C:\Users\sduraisami\Envs\myvpndashboard\lib\site-packages\paramiko\client.py", line 472, in exec_command
chan = self._transport.open_session(timeout=timeout)
File "C:\Users\sduraisami\Envs\myvpndashboard\lib\site-packages\paramiko\transport.py", line 765, in open_session
timeout=timeout)
File "C:\Users\sduraisami\Envs\myvpndashboard\lib\site-packages\paramiko\transport.py", line 889, in open_channel
raise e
EOFError

【问题讨论】:

    标签: python ssh paramiko cisco


    【解决方案1】:

    (至少有一些)众所周知,Cisco 路由器不支持一个“exec”请求中的多个命令: https://the.earth.li/~sgtatham/putty/latest/htmldoc/Chapter3.html#using-cmdline-m

    对于某些服务器(尤其是 Unix 系统),您甚至可以在此文件中放置多行并依次执行多个命令,或整个 shell 脚本; 但这可以说是一种滥用,不能指望在所有服务器上都有效。特别是,众所周知,它不适用于某些“嵌入式”服务器,例如 Cisco 路由器


    通常,您可以在同一连接上多次运行exec_command。但思科似乎也无法做到这一点。

    那么我建议您坚持为每个命令重新打开会话。虽然效率低下,但它是一种可靠的方法。


    如果效率低下不可接受,您可以使用 shell 通道,如:

    channel = ssh.invoke_shell()
    channel.send('command 1\n')
    channel.send('command 2\n')
    channel.send('command 3\n')
    while not channel.recv_ready():
        time.sleep(3)
    out = channel.recv(9999)
    print out
    

    但这并不可靠。很难判断一个命令的输出何时完成而另一个命令的输出何时开始。如果您已经获得所有输出,也很难判断。而且由于 Paramiko 总是使用 PTY,你会得到很多不需要的输出,比如提示、命令回显等。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,并且能够解决该问题。我没有使用 exec_command() 函数,而是打开了一个 shell 会话,然后将 send() 函数与我创建的 shell 对象一起使用。

      from time import sleep
      import paramiko
      
      username = "username" 
      password = "password"
      
      ssh = paramiko.SSHClient()
      ssh.load_system_host_keys()
      ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
      
      
      ssh.connect(
          ip_address, 
          port=22, 
          username=username, 
          password=password, 
          look_for_keys=False, 
          banner_timeout=200
      )
      connection = ssh.invoke_shell()
      
      
      connection.send("show int desc | i Tu")
      output = connection.recv(65535)
      print(output.decode("UTF-8"))
      sleep(.5)
      connection.send("\n")
      
      
      connection.send("show ip interface brief | i Tunnel")
      output = connection.recv(65535)
      print(output.decode("UTF-8"))
      sleep(.5)
      connection.send("\n")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-18
        • 2020-01-30
        • 2018-10-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多