代码之家  ›  专栏  ›  技术社区  ›  user2833297

python、paramiko、ssh异常ssh会话未激活

  •  5
  • user2833297  · 技术社区  · 9 年前

    我正在编写一个python脚本,该脚本将发送到网络中的每个交换机,并发出一个副本运行配置TFTP命令,以备份交换机的运行配置。我正在使用windows,并使用Python 2.7中的paramiko库。

    脚本本身非常简单,它所做的就是创建一个名为“Backups”的目录(如果还不存在),以及另一个命名为今天日期的目录,然后将该目录用于TFTP。然后启动TFTP服务器。然后,它只需通过ssh发出复制命令。

    我试图克服的这个问题是在connectSwitch()期间。特别是在第二个ssh.exec_command('x.x.x.x')上。如果您不知道交换机,则发送第一个命令是运行config tftp的副本,交换机请求主机,然后发送第二个命令,其中包含主机IP。第三个命令是文件所在的目录。

    import paramiko
    import getpass
    import os
    import time
    from datetime import date
    
    paramiko.util.log_to_file("filename.log")
    
    d = date.today()
    filename = d.strftime("%Y.%m.%d")
    
    UUser = "first.last"
    print UUser
    UPass = getpass.getpass('Enter your Password: ')
    
    def writeFile(text, Host):#Writes to the Switches backup File
        fl = open(Host+".txt", 'w')
        fl.write(text)
    
    def openIPs():#Opens the "IPs" file
        fi = open('IPs.txt', 'r')
        content = fi.readlines()
        fi.close()
        print len(content)
        makeDirBackUp()     #Creates "Backup" Dir
        makeDir()           #Creates a Directory based and named on todays date
        for item in content:
            response = os.system("ping -n 1 " +item)
            if response == 0:
                print  item + "PING STATUS: SUCCESS"
                print "BACKING UP CONFIG..."
                connectSwitch(UUser, UPass, item.strip('\n'))   #SSH connection to Switch
            else:
            print item + "PING STATUS: FAIL"
    
    def makeDir():#Creates a Directory based and named on todays date
        if not os.path.exists(filename):
            os.makedirs(filename)
        os.chdir(filename)
    
    def makeDirBackUp():#Creates "Backup" Dir
        if not os.path.exists("Backups"):
            os.makedirs("Backups")
        os.chdir("Backups")
    
    def connectSwitch(UUser, UPass, Host):#SSH connection to Switch
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(Host, port=22, username=UUser, password=UPass)
        print "Command #1"
        sendtoCRT = 'copy running-config tftp'
    
        stdin, stdout, stderr = ssh.exec_command(sendtoCRT)
        print "Command #1 sent"
        print sendtoCRT
        time.sleep(1)
        print "readlines for Command #1"
    
    
        print "Command #2"
        stdin, stdout, stderr = ssh.exec_command('10.10.10.10')
        time.sleep(1)
        print "Command #2 Sent"
    
        print "Command #3"
        stdin, stdout, stderr = ssh.exec_command('Backups/'+filename+'/'+Host)
        time.sleep(1)
        print "Command #3 Sent"
    
    
    
    def startTFTP():
        sendToOS="tftpd32.exe"
        exe1 = os.system(sendToOS)
        sendToOS='\n'
        exe = os.system(sendToOS)
        exe = os.system(sendToOS)
    
    startTFTP()
    openIPs()
    

    我的错误发生在connectSwitch()中。

    Traceback (most recent call last):
      File "C:\Users\first.last\Documents\Backups\paramikoConnect.py", line 98, in <module> openIPs()
      File "C:\Users\first.last\Documents\Backups\paramikoConnect.py", line 32, in openIPs connectSwitch(UUser, UPass, item.strip('\n'))   #SSH connection to Switch
      File "C:\Users\first.last\Documents\Backups\paramikoConnect.py", line 68, in connectSwitch stdin, stdout, stderr = ssh.exec_command('138.86.51.189')
      File "C:\Python27\lib\site-packages\paramiko-1.15.2-py2.7.egg\paramiko\client.py", line 341, in exec_command chan = self._transport.open_session()
      File "C:\Python27\lib\site-packages\paramiko-1.15.2-py2.7.egg\paramiko\transport.py", line 615, in open_session max_packet_size=max_packet_size)
      File "C:\Python27\lib\site-packages\paramiko-1.15.2-py2.7.egg\paramiko\transport.py", line 696, in open_channel raise SSHException('SSH session not active')
    paramiko.ssh_exception.SSHException: SSH session not active
    

    任何人对此都有任何想法。我在paramiko中找不到关于错误文档的更多信息,所以如果有人知道在哪里可以找到它,请延迟。net/paramiko/docs/似乎不久前就被下线了。

    但即使使用 https://web.archive.org/web/20140425222451/http://www.lag.net/paramiko/docs/ ,这里似乎没有什么。

    非常感谢你们!

    编辑:将第一个“sendtoCRT”更改为不再包含:\,因为分三步执行命令时不需要它。然而,这似乎也改变了我的错误

    Traceback (most recent call last):
      File "C:\Users\first.last\Documents\Backups\paramikoConnect.py", line 98,in <module> openIPs()
      File "C:\Users\first.last\Documents\Backups\paramikoConnect.py", line 32, in openIPs connectSwitch(UUser, UPass, item.strip('\n'))   #SSH connection to Switch
      File "C:\Users\first.last\Documents\Backups\paramikoConnect.py", line 68, in connectSwitch stdin, stdout, stderr = ssh.exec_command('138.86.51.189')
      File "C:\Python27\lib\site-packages\paramiko-1.15.2-py2.7.egg\paramiko\client.py", line 341, in exec_command chan = self._transport.open_session()
      File "C:\Python27\lib\site-packages\paramiko-1.15.2-py2.7.egg\paramiko\transport.py", line 615, in open_session max_packet_size=max_packet_size)
      File "C:\Python27\lib\site-packages\paramiko-1.15.2-py2.7.egg\paramiko\transport.py", line 740, in open_channel raise e
    paramiko.ssh_exception.ChannelException: (4, 'Resource shortage')
    

    我还找到了更多的文档。

    http://docs.paramiko.org/en/1.15/api/ssh_exception.html

    1 回复  |  直到 9 年前
        1
  •  7
  •   user2833297    9 年前

    好了,各位,我没有弄明白为什么我会犯这些错误。但我确实找到了工作。创建SSHClient后,使用connect,您可以调用Shell,它会打开一个通道,在您通过它发送消息后,它不会关闭,这很好。下面是我更新的connectSwitch代码,它利用了这一解决方案。

    def connectSwitch(UUser, UPass, Host):#SSH connection to Switch
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(Host, port=22, username=UUser, password=UPass)
        print "\n\nNewInvoke Shell\n"
    
        chan = ssh.invoke_shell()
        resp = chan.recv(9999)
        print resp
    
        print chan.send_ready()
        chan.send('copy running-config tftp\n')
        time.sleep(3)
        resp = chan.recv(9999)
        print resp
    
        chan.send('138.86.51.189\n')
        time.sleep(3)
        resp = chan.recv(9999)
        print resp
    
    
        chan.send('Backups/'+filename+'/'+Host+'\n')
        time.sleep(3)
        resp = chan.recv(9999)
        print resp
        print"\nEnd invoke Shell\n\n"