与Cisco路由器保持持久SSH会话

8 投票
4 回答
15694 浏览
提问于 2025-04-16 13:17

我在这个网站和其他很多地方都查找过,但一直没能解决我在执行一个命令后保持SSH连接的问题。下面是我现在的代码:

#!/opt/local/bin/python

import os  

import pexpect

import paramiko

import hashlib

import StringIO

while True:

      cisco_cmd = raw_input("Enter cisco router cmd:")

      ssh = paramiko.SSHClient()

      ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

      ssh.connect('192.168.221.235', username='nuts', password='cisco', timeout =  30)

      stdin, stdout, stderr = ssh.exec_command(cisco_cmd)

      print stdout.read()

      ssh.close()

      if  cisco_cmd == 'exit': break

我可以运行多个命令,但每次运行命令时都会新建一个SSH连接。上面的程序在我需要进入配置模式时就不管用了,因为SSH连接没有被重复使用。非常感谢任何能帮我解决这个问题的建议。

4 个回答

1

上面的程序在我需要配置模式时无法工作,因为ssh会话没有被重用。

当你把 connectclose 移到循环外面时,你的 ssh 会话就会被重用。但是每次调用 exec_command() 都是在一个新的环境中执行(通过一个新的通道),它们之间没有关系。所以你需要调整你的命令,让它们不依赖于当前环境的状态。

如果我没记错的话,有些思科设备只允许执行一次命令,然后就关闭连接。在这种情况下,你需要使用 invoke_shell(),并通过 pexpect 模块进行交互式操作(你已经导入了这个模块,但还没有使用它)。

1

你的循环就是这么做的

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.221.235', username='nuts', password='cisco', timeout =  30)
while True:
      cisco_cmd = raw_input("Enter cisco router cmd:")
      stdin, stdout, stderr = ssh.exec_command(cisco_cmd)
      print stdout.read()
      if  cisco_cmd == 'exit': break
ssh.close()

把初始化和设置的部分放到循环外面。

编辑:把close()移动了。

7

我用了Exscript这个工具,而不是paramiko,现在我可以在IOS设备上保持一个持续的连接会话。

#!/opt/local/bin/python
import hashlib
import Exscript

from Exscript.util.interact import read_login
from Exscript.protocols import SSH2

account = read_login()              # Prompt the user for his name and password
conn = SSH2()                       # We choose to use SSH2
conn.connect('192.168.221.235')     # Open the SSH connection
conn.login(account)                 # Authenticate on the remote host
conn.execute('conf t')              # Execute the "uname -a" command
conn.execute('interface Serial1/0')
conn.execute('ip address 114.168.221.202 255.255.255.0')
conn.execute('no shutdown')
conn.execute('end')
conn.execute('sh run int Serial1/0')
print conn.response

conn.execute('show ip route')
print conn.response

conn.send('exit\r')                 # Send the "exit" command
conn.close()                        # Wait for the connection to close

撰写回答