je suis nouveau sur python. j'ai écrit un script pour se connecter à un hôte et exécuter une commande
ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(Host, username=user, password=pw)
print 'running remote command'
stdin, stdout, stderr = ssh.exec_command(command)
stdin.close()
for line in stdout.read().splitlines():
print '%s$: %s' % (Host, line)
if outfile != None:
f_outfile.write("%s\n" %line)
for line in stderr.read().splitlines():
print '%s$: %s' % (Host, line + "\n")
if outfile != None:
f_outfile.write("%s\n" %line)
ssh.close()
if outfile != None:
f_outfile.close()
print 'connection to %s closed' %Host
except:
e = sys.exc_info()[1]
print '%s' %e
fonctionne bien quand la commande à distance n'a pas besoin d'un terminal. J'ai trouvé un exemple invoke_Shell Session SSH imbriquée avec Paramiko . cette solution ne me convient pas, car si un serveur a une invite qui n'est pas spécifiée dans mon script -> boucle infinie ou une invite spécifiée dans le script est une chaîne dans le texte de retour -> toutes les données ne seront pas reçues . Existe-t-il une meilleure solution, peut-être où stdout et stderr sont renvoyés comme dans mon script?
Vous trouverez une documentation complète sur l'API paramiko à l'adresse suivante: http://docs.paramiko.org/fr/stable/index.html
J'utilise la méthode suivante pour exécuter des commandes sur un client protégé par mot de passe:
import paramiko
import sys
nbytes = 4096
hostname = 'hostname'
port = 22
username = 'username'
password = 'password'
command = 'ls'
client = paramiko.Transport((hostname, port))
client.connect(username=username, password=password)
stdout_data = []
stderr_data = []
session = client.open_channel(kind='session')
session.exec_command(command)
while True:
if session.recv_ready():
stdout_data.append(session.recv(nbytes))
if session.recv_stderr_ready():
stderr_data.append(session.recv_stderr(nbytes))
if session.exit_status_ready():
break
print 'exit status: ', session.recv_exit_status()
print ''.join(stdout_data)
print ''.join(stderr_data)
session.close()
client.close()
Il y a quelque chose qui ne va pas avec la réponse acceptée, elle apporte parfois (de manière aléatoire) une réponse tronquée du serveur. Je ne sais pas pourquoi, je n'ai pas enquêté sur la cause défectueuse de la réponse acceptée car ce code fonctionnait parfaitement pour moi:
import paramiko
ip='server ip'
port=22
username='username'
password='password'
cmd='some useful command'
ssh=paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip,port,username,password)
stdin,stdout,stderr=ssh.exec_command(cmd)
outlines=stdout.readlines()
resp=''.join(outlines)
print(resp)
stdin,stdout,stderr=ssh.exec_command('some really useful command')
outlines=stdout.readlines()
resp=''.join(outlines)
print(resp)
Le code de @ThePracticalOne est idéal pour afficher l'utilisation, sauf pour une chose: Parfois la sortie serait incomplète. (session.recv_ready()
devient vrai après la if session.recv_ready():
, alors que session.recv_stderr_ready()
et session.exit_status_ready()
sont devenus vrais avant d'entrer dans la boucle suivante)
je pense donc à récupérer les données quand elles seront prêtes à quitter la session.
while True:
if session.exit_status_ready():
while True:
while True:
print "try to recv stdout..."
ret = session.recv(nbytes)
if len(ret) == 0:
break
stdout_data.append(ret)
while True:
print "try to recv stderr..."
ret = session.recv_stderr(nbytes)
if len(ret) == 0:
break
stderr_data.append(ret)
break