2014-06-18 31 views
0

我正在编写一个脚本,它使用SSH连接到Cisco ASR9K路由器,然后执行xml命令,将用户放入shell之类的提示符中,您可以在其中发出xml请求并获取返回XML响应。我可以通过SSH进行连接并执行命令,但是我无法从交互提示中读取和写入。Paramiko使用交互式远程客户端读取和写入

session.py

import paramiko 

class Session(object): 
    """ Create a ssh session with a host using a given username and password. 

    Keyword Arguments: 
    host -- IP of the host you want to connect to via ssh (default None) 
    username -- Username to be used in authentication with the host (default None) 
    password -- Password to be used in authentication (default None) 
    """ 

    def __init__(self, host=None, username=None, password=None): 
     self._host = host 
     self._username = username 
     self._password = password 
     self._session = None 
     if host and username and password: 
      self.connect() 

     self._stdin = None 
     self._stdout = None 
     self._stderr = None 

    @property 
    def username(self): 
     return self._username 

    . 
    . 
    . 

    def connect(self): 
     """ Connect to the host at the IP address specified.""" 
     self.session = paramiko.SSHClient() 
     self.session.load_system_host_keys() 
     self.session.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
     self.session.connect(self.host, username=self.username, password=self.password, allow_agent=False, 
          look_for_keys=False) 

    def close(self): 
     self.session.close() 

    def execute_command(self, command): 
     self.stdin, self.stdout, self.stderr = self.session.exec_command(command) 

    def write(self, message): 
     print message 
     if self.stdin == None: 
      print "error with write" 
     else: 
      self.stdin.write(message) 
    #Doesn't read the xml response from the prompt 
    def read(self): 
     while not self.stdout.channel.exit_status_ready(): 
      if self.stdout.channel.recv_ready(): 
       data = self.stdout.channel.recv(1024) 
       print "Indside stdout" 
       print data 
       break 

我创建一个线程类会话对象:

class xmlThread(threading.Thread): 
    def __init__(self, xml_tuple): 
     threading.Thread.__init__(self) 
     self.xml_request = xml_tuple[0] 
     self.threadname = '-'.join([xml_tuple[1],'thread']) 


    def log(self, message): 
     with open('.'.join([self.threadname,'log']), "w+") as fp: 
      fp.write(message) 

    def run(self): 
     ssh_session = Session(host='10.17.6.111', username='lab', password='lab') 
     ssh_session.execute_command('xml echo format') #Run the command that drops into the xml prompt 
     ssh_session.read() 
     ssh_session.write(self.xml_request) 
     ssh_session.read() 
     ssh_session.close() 



def main(): 
    xml_requests = generate_xml_requests() 
    thread_list = [] 
    for xml_request in xml_requests: 
     thread_list.append(xmlThread(xml_request)) 

    for thread in thread_list: 
     thread.start() 
     thread.join() 

    #thread_list[0].start() 

if __name__ == '__main__': 
    main() 

我得到不包括XML响应的输出,我不知道为什么不读取整个缓冲区。

Output 

Indside stdout 



<?xml version="1.0" encoding="UTF-8"?> 
        <Request MajorVersion="1" MinorVersion="0"> 
         <Get> 
          <Configuration Source="CurrentConfig"> 
           <AAA> 
           </AAA> 
          </Configuration> 
         </Get> 
        </Request> 
Indside stdout 
XML> 

任何帮助将不胜感激,谢谢。

回答

0

SSHClient.exec_command()用于执行单个命令。这听起来像是您想要使用SSHClient.invoke_shell()完成交互式会话。你执行的命令返回一个xml响应加上一个“\ nXML>”提示符。您需要提取响应,并在进行交互时将提示丢弃。