2010-08-25 24 views

Respuesta

42

SSHClient es una clase de contenedor simple en torno a la funcionalidad de bajo nivel más en Paramiko. El API documentation enumera un método recv_exit_status() en la clase Channel.

Un script muy simple demostración:

$ cat sshtest.py 
import paramiko 
import getpass 

pw = getpass.getpass() 

client = paramiko.SSHClient() 
client.set_missing_host_key_policy(paramiko.WarningPolicy()) 
client.connect('127.0.0.1', password=pw) 

while True: 
    cmd = raw_input("Command to run: ") 
    if cmd == "": 
     break 
    chan = client.get_transport().open_session() 
    print "running '%s'" % cmd 
    chan.exec_command(cmd) 
    print "exit status: %s" % chan.recv_exit_status() 

client.close() 

$ python sshtest.py 
Password: 
Command to run: true 
running 'true' 
exit status: 0 
Command to run: false 
running 'false' 
exit status: 1 
Command to run: 
$ 
+0

¡¡Realmente aprecio por su respuesta !! Lo he usado en mi proyecto. Muchas gracias. Hasta ahora puedo usar paramiko en lugar de envolver el comando del sistema ssh en la programación con python. – Beyonder

+0

Es solo algo que armé al mirar el origen de SSHClient, por lo que podría no ser * óptimo *. Por cierto: si esto hace lo que quieres, es posible que quieras "aceptar" mi respuesta. – JanC

+0

Link Dead Actualiza –

195

ejemplo mucho más fácil que no implica la invocación de la clase de canal directamente:

import paramiko 

client = paramiko.SSHClient() 
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
client.connect('blahblah.com') 

stdin, stdout, stderr = client.exec_command("uptime") 
print stdout.channel.recv_exit_status() # status is 0 

stdin, stdout, stderr = client.exec_command("oauwhduawhd") 
print stdout.channel.recv_exit_status() # status is 127 
+29

Esta es la solución correcta a la pregunta. – gphilip

+1

Lo que * nice * de este ejemplo es capturar no solo EXIT (como pregunta la pregunta), sino demostrando que todavía puede obtener STDOUT y STDERR. Hace años fui confundido por el código de ejemplo anémico de Paramiko (sin falta de respeto), y para obtener EXIT recurrí a las llamadas de transporte() de bajo nivel. transport() pareció forzarte a "elegir uno" (lo cual puede no ser cierto, pero la falta de ejemplos y documentación del tutorial me llevó a creer que) ... –

5

Gracias por janc, he añadido algunas modificaciones para el ejemplo y probado en Python3, es realmente útil para mí.

import paramiko 
import getpass 

pw = getpass.getpass() 

client = paramiko.SSHClient() 
client.set_missing_host_key_policy(paramiko.WarningPolicy()) 
#client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 

def start(): 
    try : 
     client.connect('127.0.0.1', port=22, username='ubuntu', password=pw) 
     return True 
    except Exception as e: 
     #client.close() 
     print(e) 
     return False 

while start(): 
    key = True 
    cmd = input("Command to run: ") 
    if cmd == "": 
     break 
    chan = client.get_transport().open_session() 
    print("running '%s'" % cmd) 
    chan.exec_command(cmd) 
    while key: 
     if chan.recv_ready(): 
      print("recv:\n%s" % chan.recv(4096).decode('ascii')) 
     if chan.recv_stderr_ready(): 
      print("error:\n%s" % chan.recv_stderr(4096).decode('ascii')) 
     if chan.exit_status_ready(): 
      print("exit status: %s" % chan.recv_exit_status()) 
      key = False 
      client.close() 
client.close() 
+0

recibimos cualquier mensaje de error -si hay alguno- en chan.recv_stderr_ready() ?. ¿Chan.recv_stderr (4096) .decode ('ascii') devuelve un mensaje de texto? – kten

Cuestiones relacionadas