ich bin neu in Python. Ich schrieb ein Skript, um eine Verbindung zu einem Host herzustellen und einen Befehl auszuführen
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
funktioniert gut, wenn der Fernbefehl kein tty benötigt. Ich fand ein invoke_Shell-Beispiel Verschachtelte SSH-Sitzung mit Paramiko . Ich bin mit dieser Lösung nicht zufrieden, denn wenn ein Server über eine Eingabeaufforderung verfügt, die nicht in meinem Skript angegeben ist -> Endlosschleife oder eine angegebene Eingabeaufforderung im Skript ist eine Zeichenfolge im Rückgabetext -> werden nicht alle Daten empfangen . Gibt es eine bessere Lösung, wenn stdout und stderr wie in meinem Skript zurückgeschickt werden?
Eine umfangreiche Paramiko-API-Dokumentation finden Sie unter: http://docs.paramiko.org/de/stable/index.html
Ich verwende die folgende Methode, um Befehle auf einem passwortgeschützten Client auszuführen:
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()
Die akzeptierte Antwort stimmt nicht, sie bringt manchmal (zufällig) eine abgeschnittene Antwort vom Server. Ich weiß nicht warum, ich habe die fehlerhafte Ursache der akzeptierten Antwort nicht untersucht, weil dieser Code für mich perfekt funktioniert hat:
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)
Der Code von @ThePracticalOne eignet sich hervorragend zum Anzeigen der Verwendung mit einer Ausnahme: Manchmal Die Ausgabe wäre unvollständig. (session.recv_ready()
wird nach der if session.recv_ready():
auf true gesetzt, während session.recv_stderr_ready()
und session.exit_status_ready()
vor dem Eintritt in die nächste Schleife auf true gesetzt wurden.
daher denke ich daran, die Daten abzurufen, wenn sie zum Beenden der Sitzung bereit sind.
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