it-swarm.com.de

Ausführen interaktiver Befehle in Paramiko

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.

32
Sharmila

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.

28
James Brady

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.

7
afrosteve

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

4
ax25
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 habe stdout.read (1) probiert, während es funktioniert
    Ich habe stdout.readline () ausprobiert, es funktioniert auch.
    stdin, stdout, stderr = ssh.exec_command ('/ Benutzer/lteue/Downloads/uecontrol')
    stdout.read () hängt
3
kevin yu

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

3
monkut

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
0
Paweł Wojtal

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)
0
Karate Mohammed