2008-12-17 2 views
31

Ich versuche, einen interaktiven Befehl über Paramiko auszuführen. Die cmd-Ausführung versucht, ein Passwort einzugeben, aber ich weiß nicht, wie ich das Passwort über paramikos exec_command eingeben soll und die Ausführung hängt. Gibt es eine Möglichkeit, Werte an das Terminal zu senden, wenn eine cmd-Ausführung Eingaben interaktiv erwartet?Ausführen interaktiver Befehle in Paramiko

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 dies angegangen werden kann? Vielen Dank.

+1

Die Frage ist alt, aber für die Leute, die noch hier kommen via google search möchte ich ihnen das geben. Der Schlüssel ist es, einen eigenen ** Kanal ** zu bekommen [Interaktive Befehle in Python durch Paramiko Teil 1 ausführen] (https://www.youtube.com/watch?v=Jc2l- n_GYPI) [Ausführen interaktiver Befehle in Python durch Paramiko Teil 2] (https://www.youtube.com/watch?v=lLKdxIu3-A4) In diesen beiden Videos wird erklärt, wie man interaktive Befehle über paramiko ausführt, besonders das zweite Video ist Toll und wahrscheinlich was du brauchst. –

Antwort

26

Die vollständigen paramiko Verteilung Schiffe mit vielen guten demos.

Im Demos-Unterverzeichnis haben demo.py und vollständige interaktive TTY-Beispiele, die wahrscheinlich für Ihre Situation übertrieben wären.

In Ihrem Beispiel oben ssh_stdin verhält sich wie ein Standard-Python-Dateiobjekt, so ssh_stdin.write sollte so lange arbeiten, wie der Kanal noch offen ist.

Ich habe noch nie zu stdin schreiben benötigt, aber die docs legen nahe, dass ein Kanal, sobald ein Befehl beendet geschlossen ist, so die Standard-stdin.write Methode mit einem Passwort schicken wird wahrscheinlich nicht funktionieren. Es gibt Paramiko-Befehle niedrigerer Ebene auf dem Kanal selbst, die Ihnen mehr Kontrolle geben - sehen Sie, wie die Methode SSHClient.exec_command für alle blutigen Details implementiert wird.

+1

Und für diejenigen von Ihnen, die hier nur wollen, was die Ausgabe eines Befehls möglicherweise sein könnte, könnte Code sein: '(stdin, stdout, stderr) = Client.exec_command ('ls -la') drucken ("\ nstdout ist: \ n" + stdout.read() + "\ nstderr ist: \ n" + stderr.read()) ' –

+1

' SSHClient.exec_command'Link ist tot – Ludisposed

+1

Behoben defekte Verbindung. – scy

3

Ich bin mit paramiko nicht vertraut, aber diese Arbeit kann:

ssh_stdin.write('input value') 
ssh_stdin.flush() 

Informationen zu stdin:

http://docs.python.org/library/sys.html?highlight=stdin#sys.stdin

+2

HINWEIS: Achten Sie darauf, dass Sie alle Puffer, die Sie schreiben, auf die in diesem Beispiel gezeigte Weise leeren(). Vergessen (oder nicht wissen), dies zu tun, ist eine häufige Ursache für Frustration. – aculich

5

Sie benötigen Pexpect, um das Beste aus beiden Welten zu erhalten (Expect- und SSH-Wrapper).

6

Ich hatte das gleiche Problem versucht, eine interaktive SSH-Sitzung mit ssh, eine Gabelung von Paramiko.

Ich grub sich um und fand diesen Artikel:

http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

Ihr Beispiel fortzusetzen Sie

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

Der Artikel geht mehr in die Tiefe tun könnte, eine vollständig interaktive Schale um exec_command beschreibt. Ich fand das viel einfacher zu benutzen als die Beispiele in der Quelle.

+1

Der Link ist kaputt :( –

3
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 die stdout.read() wird, wenn die Verwendung hängen dierectly ohne stdout zu überprüfen. channel.recv_ready(): in während stdout.channel.exit_status_ready():

Für meinen Fall, nach dem Ausführen des Befehls auf dem Remote-Server, wartet die Sitzung auf Benutzereingaben, nach in setze 'q', es schließt die Verbindung. Aber vor Eingabe von 'q', die stdout.read() wartet auf EOF, scheint diese Methode funktioniert nicht, wenn Puffer größer ist.

  • Ich versuchte stdout.read (1) in während, es funktioniert
    Ich versuchte stdout.readline() in während, funktioniert es auch.
    stdin, stdout, stderr = ssh.exec_command ('/ Users/lteue/Downloads/uecontrol')
    stdout.read() wird hängen
+0

Dies sollte eine separate Frage gestellt werden, wenn Sie eine Antwort benötigen (wie dies eine alte Frage ist). Oder zumindest sollte es ein Kommentar zu der Frage oder eine der Antworten sein. Es kann keine Antwort sein von selbst. – Sharmila