2008-12-17 53 views
31

Estoy tratando de ejecutar un comando interactivo a través de paramiko. La ejecución de cmd intenta solicitar una contraseña, pero no sé cómo proporcionar la contraseña a través del exec_command de paramiko y se cuelga la ejecución. ¿Hay alguna manera de enviar valores al terminal si una ejecución de cmd espera la entrada de forma interactiva?Ejecutando comandos interactivos en 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") 

¿alguien sabe cómo abordó esta lata? Gracias.

+1

La pregunta es viejo, pero para las personas que todavía vienen aquí a través de la búsqueda en google, quiero darles esto. La clave es obtener su propio ** canal ** [Ejecutar comandos interactivos en Python a través de Paramiko Parte 1] (https://www.youtube.com/watch?v=Jc2l- n_GYPI) [Ejecución de comandos interactivos en Python a través de Paramiko Parte 2] (https://www.youtube.com/watch?v=lLKdxIu3-A4) En estos dos videos se explica cómo ejecutar comandos interactivos a través de paramiko, especialmente el segundo video es genial y probablemente lo que necesitas. –

Respuesta

26

Las naves de distribución paramiko completos con una gran cantidad de buena demos.

En el subdirectorio demos, demo.py y interactive.py tienen ejemplos de TTY interactivos completos que probablemente serían excesivos para su situación.

En su ejemplo anterior ssh_stdin actúa como un objeto de archivo Python estándar, por lo que ssh_stdin.write debería funcionar siempre que el canal esté abierto.

Nunca he necesitado escribir en stdin, pero los documentos sugieren que un canal se cierra tan pronto como sale un comando, por lo que el método estándar stdin.write para enviar una contraseña probablemente no funcionará. Hay comandos paramiko de nivel más bajo en el canal mismo que le dan más control: vea cómo se implementa el método SSHClient.exec_command para todos los detalles sangrientos.

+1

Y, para aquellos de ustedes que llegaron a ver solo lo que podría ser el resultado de un comando, algunos códigos podrían ser: '(stdin, stdout, stderr) = Client.exec_command ('ls-la') imprimir ("\ nstdout es: \ n" + stdout.read() + "\ nstderr is: \ n" + stderr.read()) ' –

+1

' SSHClient.exec_command'Link está muerto – Ludisposed

+1

Se ha corregido el enlace roto. – scy

3

no estoy familiarizado con paramiko, pero esto puede funcionar:

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

Para obtener información sobre la entrada estándar:

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

+2

NOTA: siempre asegúrese de enjuagar() cualquier búfer que esté escribiendo de la manera en que este ejemplo se muestra correctamente; olvidar (o no saber) hacer esto es una causa común de frustración. – aculich

5

Necesita Pexpect para obtener lo mejor de ambos mundos (contenedores de esperar y ssh).

6

Tuve el mismo problema al tratar de hacer una sesión interactiva ssh usando ssh, un tenedor de Paramiko.

Cavé alrededor y encontré este artículo:

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

Para continuar con su ejemplo, usted podría hacer

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

El artículo continúa más en profundidad, que describe una cubierta totalmente interactivo en torno exec_command. Encontré esto mucho más fácil de usar que los ejemplos en la fuente.

+1

El enlace está roto :( –

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

Por qué la stdout.read() colgará si el uso dierectly sin comprobar la salida estándar. channel.recv_ready(): en while stdout.channel.exit_status_ready():

En mi caso, después de ejecutar el comando en el servidor remoto, la sesión está esperando la entrada del usuario, después de en pon 'q', cerrará la conexión. Pero antes de ingresar 'q', el stdout.read() esperará EOF, parece que este método no funciona si el buffer es más grande.

  • me trataron stdout.read (1) en el tiempo, funciona
    Probé stdout.readline() en el tiempo, funciona también.
    stdin, stdout, stderr = ssh.exec_command ('/ Usuarios/lteue/Descargas/uecontrol')
    stdout.read() colgará
+0

Esto debería hacerse una pregunta por separado si necesita una respuesta (ya que esta es una pregunta antigua). O al menos debería ser un comentario sobre la pregunta o una de las respuestas. No puede ser una respuesta por sí mismo. – Sharmila