Réponses:
SSHClient est une classe wrapper simple autour des fonctionnalités de niveau inférieur de Paramiko. La documentation de l'API répertorie une recv_exit_status()
méthode sur la Channel
classe.
Un script de démonstration très simple:
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()
Exemple de son exécution:
$ 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:
$
recv_exit_status
, vous ne pouvez pas l'utiliser de cette façon, car le code peut se bloquer. Vous devez consommer la sortie de la commande en attendant la fin de la commande. Voir Paramiko ssh die / hang avec une grande sortie .
Un exemple beaucoup plus simple qui n'implique pas d'appeler directement la classe de canal "de niveau inférieur" (c'est-à-dire - PAS en utilisant la client.get_transport().open_session()
commande):
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
, vous ne pouvez pas l'utiliser de cette façon, car le code peut se bloquer. Vous devez consommer la sortie de la commande en attendant la fin de la commande. Voir Paramiko ssh die / hang avec une grande sortie .
Merci pour JanC, j'ai ajouté quelques modifications pour l'exemple et testé en Python3, c'est vraiment utile pour moi.
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()
Dans mon cas, la mise en mémoire tampon de sortie était le problème. En raison de la mise en mémoire tampon, les sorties de l'application ne sortent pas de manière non bloquante. Vous pouvez trouver la réponse sur la façon d'imprimer la sortie sans mise en mémoire tampon ici: Désactivez la mise en mémoire tampon de sortie . Pour faire court, lancez simplement python avec l'option -u comme ceci:
> python -u script.py