Парамико ожидает отправки команды до получения ожидаемого результата

#python-3.x #paramiko

Вопрос:

Я пытаюсь настроить маршрутизаторы с помощью скрипта python и хотел использовать paramiko для выполнения этой работы. Функция change_password является частью класса и содержит следующие строки paramiko-expect (с self.ssh_client в качестве экземпляра paramiko.SSHClient):

 with SSHClientInteraction(self.ssh_client, timeout=5, display=True) as self.interact:
    # change password
    prompt = '.*root@cb_park:~#.*'
    self.interact.expect(prompt)
    self.interact.send('passwd')
    self.interact.expect(['.*Changing password for root.*', '.*New password:.*'])
    self.interact.send('NewPassword')
    self.interact.expect('.*Retype password:.*')
    self.interact.send('NewPassword')
    self.interact.expect(['.*passwd: password for root changed by root.*', prompt])

    # modify firstlogin
    self.interact.send('uci delete vuci.main.firstlogin')
    self.interact.expect(prompt)
    self.interact.send('uci commit')
    self.interact.expect(prompt)
 

Однако иногда команда «Отправить» выполняется до появления запроса. Например, в следующем сценарии:

 root@cb_park:~# passwd
Changing password for root
New password: 
Retype password: 
passwd: password for root changed by root
root@cb_park:~# uci delete vuci.main.firstlogin
uci commit
uci: Entry not found
root@cb_park:~# uci commit
 

«фиксация uci» выполняется, даже если ожидаемое приглашение не было выдано. Иногда это даже происходит во второй строке, и новый пароль выполняется сразу после «Смены пароля для root», даже если «Новый пароль:» не был выдан, что приводит к тайм-ауту сразу после:

 root@cb_park:~# passwd
Changing password for root
NewPassword
New password: EXCESS TIME RECV_READY TIMEOUT, did you expect() before a send()

Retype password: EXCESS TIME RECV_READY TIMEOUT, did you expect() before a send()

Passwords don't match
passwd: password for root is unchanged
root@cb_park:~#
 

Я действительно не знаю, в чем может быть ошибка или как ее отлаживать. Есть идеи?

парамико 2.8.0

парамико-ожидайте 0.3.0

Python 3.8.10

Твое здоровье, Йен

Ответ №1:

на случай, если у кого-нибудь возникнет подобная проблема:

Я вынул многострочное ожидание и заменил его ожиданием только последней строки. Наверное, я неправильно понял документы и подумал, что мне придется ожидать обеих строк. Новый код, приведенный ниже, работает без тайм-аута.

 with SSHClientInteraction(self.ssh_client, timeout=5, display=True) as self.interact:
    # change password
    prompt = '.*root@cb_park:~#.*'
    self.interact.expect(prompt)
    self.interact.send('passwd')
    self.interact.expect('.*New password:.*') # instead of self.interact.expect(['.*Changing password for root.*', '.*New password:.*'])
    self.interact.send('NewPassword')
    self.interact.expect('.*Retype password:.*')
    self.interact.send('NewPassword')
    self.interact.expect(prompt) # instead of self.interact.expect(['.*passwd: password for root changed by root.*', prompt])

    # modify firstlogin
    self.interact.send('uci delete vuci.main.firstlogin')
    self.interact.expect(prompt)
    self.interact.send('uci commit')
    self.interact.expect(prompt)
 

Иан