Ich versuche, einen interaktiven Befehl über Paramiko auszuführen. Die cmd-Ausführung versucht, zur Eingabe eines Kennworts aufzufordern, aber ich weiß nicht, wie ich das Kennwort durch den exec_command von paramiko eingeben soll. Gibt es eine Möglichkeit, Werte an das Terminal zu senden, wenn eine Ausführung von cmd interaktiv Eingaben erwartet?
ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")
Weiß jemand, wie man das ansprechen kann? Vielen Dank.
Die vollständige Paramiko-Distribution enthält viele gute Demos .
In dem Demos-Unterverzeichnis haben demo.py
und interactive.py
vollständige interaktive TTY-Beispiele, die für Ihre Situation wahrscheinlich übertrieben wären.
In Ihrem obigen Beispiel verhält sich ssh_stdin
wie ein Standard-Python-Dateiobjekt. ssh_stdin.write
sollte also funktionieren, solange der Kanal noch geöffnet ist.
Ich habe noch nie nach stdin schreiben müssen, aber die Dokumente deuten darauf hin, dass ein Kanal geschlossen wird, sobald ein Befehl beendet wird. Die Standardmethode stdin.write
zum Senden eines Kennworts funktioniert daher wahrscheinlich nicht. Es gibt auf dem Kanal selbst kleinere Paramiko-Befehle, die Ihnen mehr Kontrolle geben - sehen Sie, wie die SSHClient.exec_command
-Methode für alle gory-Details implementiert wird.
Ich hatte das gleiche Problem beim Versuch, eine interaktive ssh-Sitzung mit Hilfe von ssh zu erstellen, einem Zweig von Paramiko.
Ich grub herum und fand diesen Artikel:
http://jessenoller.com/2009/02/05/ssh-programming-mit-paramiko-completely-different/
Um Ihr Beispiel fortzusetzen, könnten Sie tun
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")
ssh_stdin.write('password\n')
ssh_stdin.flush()
output = ssh_stdout.read()
In diesem Artikel wird eine vollständig interaktive Shell um exec_command beschrieben. Ich fand das viel einfacher als die Beispiele in der Quelle.
Sie benötigen Pexpect, um das Beste aus beiden Welten (Expect- und SSH-Wrapper) zu erhalten.
ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(server_IP,22,username, password)
stdin, stdout, stderr = ssh.exec_command('/Users/lteue/Downloads/uecontrol-CXC_173_6456-R32A01/uecontrol.sh -Host localhost ')
alldata = ""
while not stdout.channel.exit_status_ready():
solo_line = ""
# Print stdout data when available
if stdout.channel.recv_ready():
# Retrieve the first 1024 bytes
solo_line = stdout.channel.recv(1024)
alldata += solo_line
if(cmp(solo_line,'uec> ') ==0 ): #Change Conditionals to your code here
if num_of_input == 0 :
data_buffer = ""
for cmd in commandList :
#print cmd
stdin.channel.send(cmd) # send input commmand 1
num_of_input += 1
if num_of_input == 1 :
stdin.channel.send('q \n') # send input commmand 2 , in my code is exit the interactive session, the connect will close.
num_of_input += 1
print alldata
ssh.close()
Warum hängt stdout.read () bei direkter Verwendung ohne Überprüfung von stdout.channel.recv_ready (): in while stdout.channel.exit_status_ready ():
In meinem Fall wartet die Sitzung nach dem Ausführen des Befehls auf dem Remote-Server auf eine Benutzereingabe. Nach der Eingabe von 'q' wird die Verbindung beendet. Bevor jedoch 'q' eingegeben wird, wartet stdout.read () auf EOF. Dieses Verfahren scheint nicht zu funktionieren, wenn der Puffer größer ist.
Ich bin mit paramiko nicht vertraut, aber das kann funktionieren:
ssh_stdin.write('input value')
ssh_stdin.flush()
Für Informationen zu stdin:
http://docs.python.org/library/sys.html?highlight=stdin#sys.stdin
Schauen Sie sich das Beispiel an und machen Sie es auf ähnliche Weise
(sorce from http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/ ):
ssh.connect('127.0.0.1', username='jesse',
password='lol')
stdin, stdout, stderr = ssh.exec_command(
"Sudo dmesg")
stdin.write('lol\n')
stdin.flush()
data = stdout.read.splitlines()
for line in data:
if line.split(':')[0] == 'AirPort':
print line
Mit dieser Methode können Sie jede gewünschte Bestätigungsnachricht wie "OK" oder das Kennwort senden. Dies ist meine Lösung mit einem Beispiel:
def SpecialConfirmation(command, message, reply):
net_connect.config_mode() # To enter config mode
net_connect.remote_conn.sendall(str(command)+'\n' )
time.sleep(3)
output = net_connect.remote_conn.recv(65535).decode('utf-8')
ReplyAppend=''
if str(message) in output:
for i in range(0,(len(reply))):
ReplyAppend+=str(reply[i])+'\n'
net_connect.remote_conn.sendall(ReplyAppend)
output = net_connect.remote_conn.recv(65535).decode('utf-8')
print (output)
return output
CryptoPkiEnroll=['','','no','no','yes']
output=SpecialConfirmation ('crypto pki enroll TCA','Password' , CryptoPkiEnroll )
print (output)