Paramiko使用交互式远程客户端进行读写

时间:2014-06-18 15:36:41

标签: python xml ssh paramiko

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

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> 

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

1 个答案:

答案 0 :(得分:0)

SSHClient.exec_command()用于执行单个命令。听起来你想要使用SSHClient.invoke_shell()来完成交互式会话。您执行的命令返回了一个xml响应加上一个“\ nXML&gt;”提示。当你进行交互时,你需要提取响应并抛出提示。