Respuestas:
SSHClient es una clase contenedora simple alrededor de la funcionalidad de nivel más bajo en Paramiko. La documentación de la API enumera un método recv_exit_status () en la clase Channel.
Un guión de demostración muy simple:
$ 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:
$
Un ejemplo mucho más fácil que no implica invocar directamente la clase de canal de "nivel inferior" (es decir, NO usar el client.get_transport().open_session()
comando):
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
recv_exit_status
, no puede usarlo de esta manera, ya que el código puede bloquearse. Tienes que consumir la salida del comando, mientras esperas a que termine el comando. Vea Paramiko ssh morir / colgar con gran salida .
Gracias por JanC, agregué algunas modificaciones para el ejemplo y lo probé en Python3, fue 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()
En mi caso, el búfer de salida fue el problema. Debido al almacenamiento en búfer, las salidas de la aplicación no salen sin bloqueo. Puede encontrar la respuesta sobre cómo imprimir la salida sin almacenar en búfer aquí: Desactive el almacenamiento en búfer de salida . Para abreviar, simplemente ejecute python con la opción -u como esta:
> python -u script.py