web-dev-qa-db-fra.com

Comment pouvez-vous obtenir le code de retour SSH en utilisant Paramiko?

client = paramiko.SSHClient()
stdin, stdout, stderr = client.exec_command(command)

Est-il possible d'obtenir le code retour de la commande?

Il est difficile d'analyser tous les stdout/stderr et de savoir si la commande s'est terminée avec succès ou non.

79
Beyonder

SSHClient est une simple classe wrapper qui regroupe les fonctionnalités de niveau inférieur de Paramiko. La Documentation API répertorie une méthode recv_exit_status () sur la classe Channel.

Un script de démonstration très 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: 
$
46
JanC

Exemple beaucoup plus simple qui n’implique pas l’appel direct de la classe de canal:

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
229
apdastous

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()
5
perillaseed

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 une sortie sans mettre en mémoire tampon ici: Désactiver la mise en mémoire tampon de sortie . Pour faire court, lancez python avec l'option -u comme ceci:

> python -u script.py

0
Youngmin Kim