python pexpect: SSHing luego actualizando la fecha

¡Finalmente tengo mi script python pexpect funcionando a excepción de la parte más importante que actualiza la fecha! Puedo SSH en la caja pero mi segundo comando no se ejecuta correctamente. Me he estado golpeando la cabeza contra la pared tratando de averiguar por qué. He comprobado la salida de la picadura y debería estar funcionando en base a lo que está codificado. No soy un experto en python o pexpect, así que necesito un poco de ayuda para averiguar por qué mi tiempo no se está actualizando.

mi código original :

list = ["089"] sn = 0 ssh_new_conn = 'Are you sure you want to continue connecting' class ThreadClass(threading.Thread): def __init__(self, index): super(ThreadClass, self).__init__() self.index = index def run(self): sn = storelist[self.index] #easterndate = (currenttime + datetime.timedelta(0, 3600)) #easterndate = easterndate est = timezone('US/Eastern') cst = timezone('US/Central') #currenttime = (datetime.now()) currenttime = cst.localize(datetime.now()) #easterndate = (currenttime + timedelta(0, 3600)) #easterndate = easterndate.strftime("%a %b %d %H:%M:%S %Z %Y") easterndate = currenttime.astimezone(est).strftime("%a %b %d %H:%M:%S %Z %Y") command1 = "/usr/bin/ssh %(username)s@%(hostname)s" % locals() command2 = " sudo date -s\"%(easterndate)s\"" % locals() command3 = " sudo date -s\"%(currenttime)s\"" % locals() now = datetime.now() #central if sn == "073" or sn == "066" or sn == "016": #or sn == "022": p = pexpect.spawn((command1 + command3), timeout=360) #eastern else: print(command1 + command2) p = pexpect.spawn((command1 + command2), timeout=360) # Handles the 3 possible connection outcomes: # a) Ssh to the remote host for the first time, triggering 'Are you sure you want to continue connecting' # b) ask you for password # c) No password is needed at all, because you already have the key. i = p.expect([ssh_new_conn,'[pP]assword:',pexpect.EOF]) print ' Initial pexpect command output: ', i if i == 0: # send 'yes' p.sendline('yes') i = p.expect(['[pP]assword:',pexpect.EOF]) print 'sent yes. pexpect command output', i if i == 0: # send the password print "logging into box %(sn)s" % locals() p.sendline(password) print "login successful" print "Setting the time..." elif i == 1: # send the password print "logging into box %(sn)s" % locals() p.sendline(password) print "login successful" print "Setting the time..." p.close() elif i == 2: print "pexpect faced key or connection timeout" pass print p.before for i in range(len(list)): t = ThreadClass(i) t.start() 

Código nuevo :

 class ThreadClass(threading.Thread): def __init__(self, index): super(ThreadClass, self).__init__() self.index = index def run(self): try: sn = storelist[self.index] username = raw_input('username: ') password = raw_input('password: ') hostname = "[hostname]" est = timezone('US/Eastern') cst = timezone('US/Central') #currenttime = (datetime.now()) currenttime = cst.localize(datetime.now()) #easterndate = (currenttime + timedelta(0, 3600)) #easterndate = easterndate.strftime("%a %b %d %H:%M:%S %Z %Y") easterndate = currenttime.astimezone(est).strftime("%a %b %d %H:%M:%S %Z %Y") ssh = pxssh.pxssh() print(hostname + " " + username + " " + password) ssh.login(hostname, username, password) if sn == "073" or sn == "066" or sn == "016": #or sn == "022": ssh.sendline ('date') # run a command ssh.prompt() # match the prompt print(s.before) # print everything before the prompt. ssh.sendline ('sudo date -s\"%(currenttime)s\"' % locals()) # run a command ssh.expect('(?i)password.*:') # match password prompt for sudo ssh.sendline(password) ssh.prompt() print(s.before) ssh.logout() else: ssh.sendline ('date') # run a command ssh.prompt() # match the prompt print(s.before) # print everything before the prompt. ssh.sendline ('sudo date -s\"%(easterndate)s\"' % locals()) # run a command ssh.expect('(?i)password.*:') # match password prompt for sudo ssh.sendline(password) ssh.prompt() print(s.before) ssh.logout() except pxssh.ExceptionPxssh as e: print(e) for i in range(len(storelist)): t = ThreadClass(i) t.start() 

Nuevo error que estoy recibiendo :

 Traceback (most recent call last): File "./sshtest.py", line 8, in  s.login (hostname, username, password) File "/usr/lib/python2.6/dist-packages/pxssh.py", line 243, in login if not self.synch_original_prompt(): File "/usr/lib/python2.6/dist-packages/pxssh.py", line 134, in synch_original_prompt self.read_nonblocking(size=10000,timeout=1) # GAS: Clear out the cache before getting the prompt File "/usr/lib/python2.6/dist-packages/pexpect.py", line 824, in read_nonblocking raise TIMEOUT ('Timeout exceeded in read_nonblocking().') pexpect.TIMEOUT: Timeout exceeded in read_nonblocking(). 

SOLUCIÓN AL ERROR

Me di cuenta de la solución al error que estaba recibiendo. Debido a un error conocido, tuve que agregar las siguientes líneas a usr / lib / python.2.6 / dist-packages / pxssh.py:

 self.sendline() #line 134 time.sleep(0.5) #line 135 self.read_nonblocking(size=10000,timeout=1) # GAS: Clear out the cache before getting the prompt 

SOLUCIÓN AL ERROR

Me di cuenta de la solución al error que estaba recibiendo. Debido a un error conocido, tuve que agregar las siguientes líneas a usr / lib / python.2.6 / dist-packages / pxssh.py:

 self.sendline() #line 134 time.sleep(0.5) #line 135 self.read_nonblocking(size=10000,timeout=1) # GAS: Clear out the cache before getting the prompt 

Probablemente debería manejar la solicitud de contraseña de sudo (opción + -t ssh para obtener un tty) y usar p.expect(EOF) antes de p.close() para evitar matar el proceso hijo prematuramente.

Aquí hay un ejemplo basado en documentos pexpect :

 import pxssh try: s = pxssh.pxssh() s.login (hostname, username, password) s.sendline ('date') # run a command s.prompt() # match the prompt print(s.before) # print everything before the prompt. s.sendline ('sudo date') # run a command s.expect('(?i)password.*:') # match password prompt for sudo s.sendline(password) s.prompt() print(s.before) s.logout() except pxssh.ExceptionPxssh as e: print(e) 

También puedes probar fabric :

 # fabfile.py from fabric.api import run, sudo def date(): run('date') sudo('date') 

Uso:

 $ fab -H localhost,user@host date 

Para cualquier otra alma pobre como yo atrapada con Python 2.6 en 2019 y no queriendo hackear sus paquetes de sitio, pude arreglar este problema con la configuración de maxread a 1 en el constructor.

pxssh.pxssh(maxread=1)