2011-10-06 30 views
9

Antecedentes: Estoy usando python y paramiko para automatizar el proceso que paso cada vez que tengo que entregar un programa para una clase. Usamos un comando llamado "handin" para enviar el código fuente, pero esto debe hacerse desde una computadora escolar. Así que cuando envío el código desde mi casa, tengo que: sftp en los servidores de la escuela, poner los archivos en un directorio, ssh en la computadora de la escuela, usar el comando 'handin'Script Python paramiko, problemas de lectura de salida durante exec_command()

Puedo colocar archivos exitosamente en las máquinas de la escuela. El problema ocurre cuando intento usar exec_command ('handin my files') y luego leo el resultado para determinar la siguiente acción.

así que tienen

try: 
    (stdin, stdout, stderr) = client.exec_command(s) 
except: 
    print 'whoops' 
    sys.exit() 
print stdout.readlines() 

Pero esto provoca un estancamiento por alguna razón, el guión parece estar sin hacer nada y tengo que matar a la larga todo el proceso (Ctrl + C no funciona). No estoy seguro de si exec_command no se está completando correctamente (a pesar de que se está saliendo del bloque try/catch) o si tengo problemas de red o qué.

¿Alguna idea?

actualización:

El problema es con la interacción con el comando handin durante la ejecución. Después de ejecutar el comando, handin puede o no seguir ejecutándose. Si es la primera vez que lo envía, dice éxito, bla, bla, y termina de ejecutarse. Todo está bien. Pero si vuelvo a enviar tengo que autorizar una sobrescritura (stdin.write ('y')) para cada archivo.

TL/DR:

¿Cómo puedo comprobar si un exec_command() todavía se está ejecutando, a la espera para la entrada, y readline() desde la salida estándar en consecuencia?

+0

¿Tiene una solución para TL/DR? Además, ¿cómo puedo saber el texto antes de esperar la entrada, p. @ contraseña ... –

Respuesta

5

El problema podría ser que el comando remoto está esperando la entrada (se espera que escriba algo en stdin, sin saber que no va a hacerlo a menos que así lo diga). Pruebe stdin.channel.shutdown_write() (Creo que stdin.close() por sí mismo no funcionará: eso solo causará un color)

+0

Eso es lo que necesitaba hacer una línea de lectura para verificar. Si transfiere varias veces, le pregunta si desea sobrescribir [y/N] para cada archivo, si es la primera vez que no necesita más información. ¿Cómo verifico el resultado durante exec_command? – macgregor

+0

stdout.readlines() en realidad está leyendo el resultado de los comandos ssh, no la entrada de "lectura" del script y enviándolo al comando ssh. Para hacer eso necesitas stdin.write(). – bdk

+0

Soy consciente de eso, lo malinterpretas.Actualicé mi publicación original, tal vez eso aclare las cosas – macgregor

8

No veo nada de malo con el snippit de código anterior. El siguiente programa es un script completo que se registra en un host y ejecuta el comando ls para ver los archivos. Lo intenté y me funciona. Tal vez intente esto y vea si funciona para usted. Si no funciona, sospecho que hay algún problema específico para el servidor ssh, el comando que está ejecutando o la instalación de paramiko. Si funciona para usted, solo es cuestión de hacer cambios a esto para avanzar hacia su funcionalidad existente y ver dónde se rompe.

import paramiko 
ssh=paramiko.SSHClient() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect('<ip address here>',username='<username here>',password='<password here>') 
stdin,stdout,stderr = ssh.exec_command("ls /") 
print stdout.readlines() 

Si funciona para ti, mi siguiente sugerencia sería intentar reemplazar los 'ls /' con el comando handin real que usted está intentando ejecutar. Es posible que el comando se cuelgue en espera de la entrada del usuario, etc.

+0

sí, estoy bien conectado, los comandos básicos funcionan muy bien. Estoy tratando de usar la línea de lectura para averiguar qué introducir a continuación durante la ejecución del comando – macgregor

+0

Es casi seguro que su comando de mano luego. Espera un comportamiento interactivo. Mire este ejemplo que usa 'sudo dmesg' en el enlace y, por lo tanto, tiene que responder a una solicitud de contraseña: http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/ – bdk

+0

bien, necesito hacer esto de forma dinámica sin embargo. ¿Hay alguna manera de leer stdout durante la ejecución del comando para comprobar cuántas veces tengo que escribir 'y' – macgregor