2010-01-25 11 views
15

Estoy utilizando el subproceso módulo para llamar a un programa externo (plink.exe) para iniciar sesión en un servidor; pero cuando llamo a comunicarse para leer la salida, está bloqueando. El código es el siguiente:python subprocess comunicar() bloque

import subprocess 
process = subprocess.Popen('plink.exe [email protected] -pw 123456'.split(), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
print process.communicate() #block here 

Sé que el bloque se debe a que plink.exe aún en marcha; pero necesito leer la salida antes de que termine el subproceso. ¿Hay alguna forma de hacer eso?

+0

¿Es necesario interactuar con plink, o sólo tiene que hacer la llamada y leer la salida estándar sin bloqueo? – Khelben

+0

relacionado: [Python: lee la entrada de transmisión de subprocess.communicate()] (http://stackoverflow.com/q/2715847/4279) – jfs

Respuesta

26

El propósito del método communicate es esperar a que el proceso finalice y devolver todos los resultados. Si no desea esperar, no llame al communicate. En su lugar, lea el atributo stdout o stderr para leer la salida.

Si el proceso da salida a stdout y stderr (y desea leerlo por separado), deberá tener cuidado de leer ambos sin bloqueo, o puede bloquearlos. Esto es bastante difícil en Windows, y es posible que desee utilizar el módulo pexpect en su lugar.

+0

'pexpect' no funciona en Windows. ['asyncio'] (http://stackoverflow.com/a/20697159/4279) o [hilos] (http://stackoverflow.com/a/4896288/4279) podrían usarse para leer ambas secuencias sin bloquear. – jfs

0

Me enfrenté a una situación similar en la que tuve que ejecutar un solo comando lmstat -a y luego obtener la salida del terminal.

Si sólo tiene que ejecutar un solo comando y luego leer la salida, se puede utilizar el siguiente código:

import subprocess 

Username = 'your_username' 
Password = 'your_password' 
IP = 'IP_of_system' 
Connection_type = '-ssh' #can have values -ssh -telnet -rlogin -raw -serial 

p = subprocess.Popen(['plink', Connection_type, '-l', Username, '-pw', Password, IP], \ 
        shell = False, stdin=subprocess.PIPE, stdout=subprocess.PIPE) 
out, err = p.communicate('lmstat -a\nexit\n'.encode()) 
print(out.decode()) 
+1

Como dijo @Thomas, este es un enfoque de bloqueo y no de bloqueo. – Fookatchu

Cuestiones relacionadas