Неожиданный вывод в Парамико - PullRequest
3 голосов
/ 25 апреля 2019

Я использую Paramiko для отправки некоторых команд на маршрутизатор, но выводимый текст почти не читается.

Как удалить 'b' и \r\n в выводе?

Как правильно разбивать строки?

Этот фрагмент кода, предположительно, должен правильно разбивать строки:

def print_lines(self, data):
        last_line = data
        if '\n' in data:
            lines = data.splitlines()
            for i in range(0, len(lines)-1):
                print((lines[i]))
            last_line = lines[len(lines) - 1]
            if data.endswith('\n'):
                print(last_line)
                last_line = ''
        return last_line

Полный код:

class ssh:
    shell = None
    client = None
    transport = None

    def __init__(self, address, username, password):
#        print(("Connecting to server on ip", str(address) + "."))
        self.client = paramiko.client.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
        self.client.connect(address, username=username, password=password, look_for_keys=False)
        self.transport = paramiko.Transport((address, 22))
        self.transport.connect(username=username, password=password)

        thread = threading.Thread(target=self.process)
        thread.daemon = True
        thread.start()

    def close_connection(self):
        if(self.client != None):
            self.client.close()
            self.transport.close()

    def open_shell(self):
        self.shell = self.client.invoke_shell()

    def send_shell(self, command):
        if(self.shell):
            self.shell.send(command + "\n")
        else:
            print("<h1>Shell não aberta.</h1>")

    def process(self):
        global strdata, fulldata
        while True:
            # Print data when available
            if self.shell is not None and self.shell.recv_ready():
                alldata = self.shell.recv(1024)
                while self.shell.recv_ready():
                    alldata += self.shell.recv(1024)
                strdata = strdata + str(alldata)
                fulldata = fulldata + str(alldata)
                strdata = self.print_lines(strdata) # print all received data except last line

    def print_lines(self, data):
        last_line = data
        if '\n' in data:
            lines = data.splitlines()
            for i in range(0, len(lines)-1):
                print((lines[i]))
            last_line = lines[len(lines) - 1]
            if data.endswith('\n'):
                print(last_line)
                last_line = ''
        return last_line


sshUsername = "admin"
sshPassword = "password"
sshServer = "192.168.40.165"

connection = ssh(sshServer, sshUsername, sshPassword)
connection.open_shell()
connection.send_shell('en')
connection.send_shell('conf t')
connection.send_shell('hostname R5')
time.sleep(1)
print('<h1>'+fulldata+'</h1>')   # This contains the complete data received.
connection.close_connection()

Я ожидал этого:

R5#en
R%#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R5(config)#hostname R5
R5(config)#

Но это был результат:

b'\r\nR5#'b'e'b'n'b'\r\n'b'R5#'b'c'b'o'b'n'b'f'b' t'b'\r\n'b'Enter configuration commands, one per line. End with CNTL/Z.\r\nR5(config)#'b'h'b'o'b's'b't'b'n'b'a'b'm'b'e'b' 'b'R'b'5'b'\r\n'b'R5(config)#'

Как я могу правильно получить разрывы строк?Пожалуйста, прости мой большой пост.

Ответы [ 2 ]

1 голос
/ 25 апреля 2019

Похоже, вы имеете дело с bytes() объектом ( больше информации ), поэтому вам придется использовать метод decode(), чтобы превратить его встрока.

Например, давайте создадим объект bytes() и превратим его обратно в строку:

greeting = str("Hello World").encode("UTF-8")
print(greeting)
greeting = greeting.decode("UTF-8")
print(greeting)

Или в вашем случае:

alldata_str = alldata.decode("UTF-8")

ПРЕДУПРЕЖДЕНИЕ: Paramiko может иметь другую кодировку для своих строк, поэтому обязательно проверьте их документацию .

Удачи.

1 голос
/ 25 апреля 2019

alldata получает байты от paramiko, и вы используете str (байты), поэтому вы помещаете кавычки вокруг b'string '. вам нужно использовать декодирование для декодирования байтов

alldata_str = alldata.decode()
strdata = strdata + alldata_str
fulldata = fulldata + alldata_str

Существуют библиотеки, которые помогают с paramiko, как для маршрутизаторов netmiko , основанные на paramiko. У меня также есть библиотека, чтобы делать терминальные интерактивные SSH для устройств в целом https://github.com/filintod/pyremotelogin (также на основе paramiko). Также есть напалм (https://napalm -automation.net / blog / ) также для работы в сети.

...