2016-04-08 12 views
5

Ho intenzione di eseguire diversi comandi sull'host remoto usando paramiko, ma la sessione ssh si è chiusa dopo aver eseguito un comando.
Il codice di seguito elencati:Come mantenere la sessione ssh non scaduta usando paramiko?

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') 

Quindi non v'è alcun modo per fermare la sessione ssh da chiudere? O qualche alternativa per paramiko?

Aggiornamento:
ero in grado di mantenere chiamando exec_command sul mio MacBook quando è collegato a un server Linux, ma la sessione ssh chiusa automaticamente dopo exec_command una volta su un server Linux quando è collegato a un interruttoree sollevò un
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 

esiste un modo per tenere sessione ssh paramiko attiva per tutto il tempo?

Il paramiko di debug informazioni modalità restituito come segue:

partire filo (modalità client): 0x2657e10L
Connected (versione 1.99, client Comware-5,20)
algos Kex: [u'diffie-Hellman -group-exchange-sha1 ', u'diffie-hellman- group14-sha1', u'diffie-hellman-group1-sha1 '] chiave del server: [u'ssh-rsa'] client criptare: [u'aes128-cbc ', u'3des-cbc', u'des-cbc '] server encrypt: [u'aes128-cbc', u'3des-cbc ', u'des-cbc'] client mac: [u'hmac-sha1 ', u'hmac-sha1-96', u'hmac-md5 ', u'hmac-md5-96'] server mac: [u'hmac-sha1 ', u'hmac-sha1-96', u'hmac -md5 ', u'hmac-md5-96'] client compresso: [u'none '] server compr: [ u'none '] client lang: [u' '] server lang: [u' '] kex segue? False
Cifrari concordati: locale = aes128-cbc, remoto = aes128-cbc
utilizzando kex diffie-hellman-group14 -sha1; tipo di chiave del server ssh-rsa; cifrario: locale aes128-cbc, remoto aes128-cbc; mac: local hmac-sha1, remote hmac-sha1; compressione: locale nessuno, remoto nessuno
Passa a nuove chiavi ...
userauth is OK
Autenticazione (password) riuscita!
[Chan 0] Max pacchetto in: 32768 byte
[Chan 1] Max packet in: 32768 byte
[Chan 0] Max packet out: 32496 byte
canale secsh 0 aperto.canale
secsh 2 Apertura fallita:
Resource carenza: carenza di risorse
[Chan 0] canale Sesch 0 richiesta ok
[Chan 0] EOF inviato (0)

+0

C'è di più nella sceneggiatura di questa? Dovresti essere in grado di continuare a chiamare 'exec_command'. – tdelaney

+0

Ciao? Stai eseguendo diversi comandi nello script o eseguendo diversi script con un comando ciascuno? – tdelaney

+0

Sono stato in grado di continuare a chiamare 'exec_command' sul mio Macbook, ma non ha funzionato su un server Linux e generato un' SSHException: paramiko.ssh_exception.SSHException: sessione SSH non attiva 'La versione Python su Mac è 2.7.11 ma su Il server Linux è 2.6.6. @tdelaney –

risposta

1

Vedo che si sta utilizzando il timeout parametro nella chiamata di connessione:

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

Dalla documentazione:

timeout (float) - un timeout opzionale (in secondi) per la connessione TCP

In uno dei miei script ho semplicemente fare:

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

che mantiene la connessione aperta fino a quando mi chiamano

ssh.close() 
+0

Stesso risultato quando si è connessi a un ** switch ** da un server Linux, ma ha funzionato correttamente quando è connesso a un server Linux da un altro. Non sembra diverso se aggiungere o meno il parametro 'timeout'. @LarsVegas –

+0

hai visto questo [SO] (http://stackoverflow.com/questions/31477121/python-paramiko-ssh-exception-ssh-session-not-active)? – LarsVegas

+0

Risolve definitivamente il problema della sessione ssh inattiva, ma quando lo eseguivo in parallelo, il canale rimaneva sospeso lì dopo aver inviato il primo comando. @LarsVegas –

1

È possibile implementare una shell interattiva utilizzando paramiko, in questo modo il canale non viene chiuso dopo l'esecuzione di un comando sulla shell remota.

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 
Problemi correlati