2016-04-08 13 views
5

Ich beabsichtige, mehrere Befehle auf Remote-Host mit paramiko, aber die SSH-Sitzung nach dem Ausführen eines Befehls geschlossen.
Der Code unten aufgeführt:Wie zu halten ssh Sitzung nicht mit Paramiko abgelaufen?

from paramiko import SSHClient 
import paramiko 
ssh = SSHClient() 
ssh.load_system_host_keys() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect(host, 22, user, passwd, timeout=3) 
stdin, stdout, stderr = ssh.exec_command('uname -a') 

So ist es eine Möglichkeit, die SSH-Sitzung vor der Schließung zu stoppen? Oder irgendwelche Alternativen für Paramiko?

aktualisieren:
konnte ich halte exec_command auf meinem MacBook anruft, wenn auf einen Linux-Server verbunden, aber die SSH-Sitzung automatisch geschlossen, nachdem exec_command einmal auf einem Linux-Server, wenn ein zu einem Schalter und angehoben verbunden
SSHException: paramiko.ssh_exception.SSHException: SSH session not active

>>> print ssh.get_transport() 
>>> <paramiko.Transport at 0xf00216d0L (unconnected)> 
>>> print ssh.get_transport().is_active() 
>>> False 
>>> print ssh.get_transport().is_authenticated() 
>>> False 

gibt es eine Möglichkeit paramiko sSH-Sitzung aktiv die ganze Zeit zu halten?

Der paramiko Debug-Modus Info zurück, wie folgend:

Anfangsfaden (Client-Modus): 0x2657e10L
Connected (Version 1.99, Client Comware-5,20)
kex algos: [u'diffie-Hellman -group-exchange-sha1 ', u'diffie-hellman-group14-sha1', u'diffie-hellman-group1-sha1 '] Serverschlüssel: [u'ssh-rsa'] Client verschlüsseln: [u'aes128-cbc ', u'3des-cbc', u'des-cbc '] Server verschlüsseln: [u'aes128-cbc', u'3des-cbc ', u'des-cbc'] client mac: [u'hmac-sha1 ',' hmac-sha1-96 ',' hmac-md5 ',' hmac-md5-96 '] server mac: [h'mac-sha1', h'mac-sha1-96 ', h'mac -md5 ', u'hmac-md5-96'] Client-Komprimierung: [u'none '] Server-Komprimierung: [ u'none '] client lang: [u' '] server lang: [u' '] kex folgt? Falsch
Codierer vereinbart: local = aes128-cbc, remote = aes128-cbc
mit kex diffie-hellman-group14 -sha1; Server Schlüsseltyp ssh-rsa; Verschlüsselung: lokal aes128-cbc, remote aes128-cbc; mac: local hmac-sha1, remote hmac-sha1; Komprimierung: lokal keine, remote keine
Zu neuen Tasten wechseln ...
userauth ist OK
Authentifizierung (Passwort) erfolgreich!
[Chan 0] Max Paket in: 32768 Bytes
[chan 1] Max Paket in: 32768 Bytes
[Chan 0] Max Paket aus: 32496 Bytes
secsh Kanal 0 geöffnet.
secsh Kanal 2 geöffnet werden kann:
Mangel Ressource: Ressourcenknappheit
[chan 0] Sesch Kanal 0 Anfrage ok
[chan 0] EOF gesendet (0)

+0

Gibt es mehr zum Skript als das? Sie sollten weiterhin 'exec_command' aufrufen können. – tdelaney

+0

Hallo? Führen Sie mehrere Befehle im Skript aus oder führen Sie mehrere Skripte mit jeweils einem Befehl aus? – tdelaney

+0

Ich konnte 'exec_command' auf meinem Macbook nennen, aber es funktionierte nicht auf einem Linux-Server und rief eine' SSHException: paramiko.ssh_exception.SSHException: SSH-Session nicht aktiv' auf. Die Python-Version auf dem Mac ist 2.7.11 aber aktiviert Linux-Server ist 2.6.6. @tdelaney –

Antwort

1

Ich sehe, Sie sind mit den timeout Parameter in der connect-Aufruf:

ssh.connect(host, 22, user, passwd, timeout=3) 

Aus der Dokumentation:

Timeout (float) - eine optionale Timeout (in Sekunden) für die TCP ich einfach

In einem meiner Skripte verbinden:

ssh = paramiko.SSHClient() 
ssh.connect(host, username=settings.user) 

, die offen die Verbindung hält bis nenne ich

+0

Gleiches Ergebnis, wenn mit einem ** Switch ** vom Linux-Server verbunden, aber es funktionierte gut, wenn von einem anderen Linux-Server verbunden ist. Es scheint nicht anders zu sein, ob man den Parameter 'timeout' hinzufügt oder nicht. @LarsVegas –

+0

hast du das [SO] (http://stackoverflow.com/questions/31477121/python-paramiko-ssh-exception-ssh-session-not-active) gesehen? – LarsVegas

+0

Es löste definitiv das inaktive SSH-Session-Problem, aber wenn ich es parallel ausführte, blieb der Kanal dort hängen, nachdem er den ersten Befehl gesendet hatte. @LarsVegas –

1

Sie können eine interaktive Shell mit paramiko implementieren, so dass der Kanal nicht geschlossen wird, nachdem ein Befehl auf der Remote-Shell ausgeführt wurde.

import paramiko 
import re 


class ShellHandler: 

    def __init__(self, host, user, psw): 
     self.ssh = paramiko.SSHClient() 
     self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
     self.ssh.connect(host, username=user, password=psw, port=22) 

     channel = self.ssh.invoke_shell() 
     self.stdin = channel.makefile('wb') 
     self.stdout = channel.makefile('r') 

    def __del__(self): 
     self.ssh.close() 

    @staticmethod 
    def _print_exec_out(cmd, out_buf, err_buf, exit_status): 
     print('command executed: {}'.format(cmd)) 
     print('STDOUT:') 
     for line in out_buf: 
      print(line, end="") 
     print('end of STDOUT') 
     print('STDERR:') 
     for line in err_buf: 
      print(line, end="") 
     print('end of STDERR') 
     print('finished with exit status: {}'.format(exit_status)) 
     print('------------------------------------') 
     pass 

    def execute(self, cmd): 
     """ 

     :param cmd: the command to be executed on the remote computer 
     :examples: execute('ls') 
        execute('finger') 
        execute('cd folder_name') 
     """ 
     cmd = cmd.strip('\n') 
     self.stdin.write(cmd + '\n') 
     finish = 'end of stdOUT buffer. finished with exit status' 
     echo_cmd = 'echo {} $?'.format(finish) 
     self.stdin.write(echo_cmd + '\n') 
     shin = self.stdin 
     self.stdin.flush() 

     shout = [] 
     sherr = [] 
     exit_status = 0 
     for line in self.stdout: 
      if str(line).startswith(cmd) or str(line).startswith(echo_cmd): 
       # up for now filled with shell junk from stdin 
       shout = [] 
      elif str(line).startswith(finish): 
       # our finish command ends with the exit status 
       exit_status = int(str(line).rsplit(maxsplit=1)[1]) 
       if exit_status: 
        # stderr is combined with stdout. 
        # thus, swap sherr with shout in a case of failure. 
        sherr = shout 
        shout = [] 
       break 
      else: 
       # get rid of 'coloring and formatting' special characters 
       shout.append(re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]').sub('', line). 
          replace('\b', '').replace('\r', '')) 

     # first and last lines of shout/sherr contain a prompt 
     if shout and echo_cmd in shout[-1]: 
      shout.pop() 
     if shout and cmd in shout[0]: 
      shout.pop(0) 
     if sherr and echo_cmd in sherr[-1]: 
      sherr.pop() 
     if sherr and cmd in sherr[0]: 
      sherr.pop(0) 

     self._print_exec_out(cmd=cmd, out_buf=shout, err_buf=sherr, exit_status=exit_status) 
     return shin, shout, sherr 
Verwandte Themen