que - subprocess python 3 example
ComprensiĆ³n de Popen.communicate (3)
Tengo un script llamado 1st.py
que crea un REPL (read-eval-print-loop):
print "Something to print"
while True:
r = raw_input()
if r == ''n'':
print "exiting"
break
else:
print "continuing"
Luego 1st.py
con el siguiente código:
p = subprocess.Popen(["python","1st.py"], stdin=PIPE, stdout=PIPE)
Y luego intenté esto:
print p.communicate()[0]
Falló, proporcionando este rastreo:
Traceback (most recent call last):
File "1st.py", line 3, in <module>
r = raw_input()
EOFError: EOF when reading a line
¿Puedes explicar lo que está pasando aquí, por favor? Cuando uso p.stdout.read()
, se cuelga para siempre.
No use comunicar (input = ""). Escribe entrada al proceso, cierra su stdin y luego lee todos los resultados.
Hazlo asi:
p=subprocess.Popen(["python","1st.py"],stdin=PIPE,stdout=PIPE)
# get output from process "Something to print"
one_line_output = p.stdout.readline()
# write ''a line/n'' to the process
p.stdin.write(''a line/n'')
# get output from process "not time to break"
one_line_output = p.stdout.readline()
# write "n/n" to that process for if r==''n'':
p.stdin.write(''n/n'')
# read the last output from the process "Exiting"
one_line_output = p.stdout.readline()
Qué harías para eliminar el error:
all_the_process_will_tell_you = p.communicate(''all you will ever say to this process/nn/n'')[0]
Pero dado que la comunicación cierra stdout
y stdin
y stderr
, no puede leer ni escribir después de llamar para comunicarse.
Su segundo bit de código inicia el primer bit de código como un subproceso con entrada y salida por canal. Luego cierra su entrada e intenta leer su salida.
El primer bit de código intenta leer desde la entrada estándar, pero el proceso que lo inició cerró su entrada estándar, por lo que llega inmediatamente a un final de archivo, que Python convierte en una excepción.
.communicate()
escribe entrada (no hay entrada en este caso por lo que simplemente cierra el subproceso ''stdin para indicar al subproceso que no hay más entrada), lee todos los resultados y espera a que salga el subproceso.
La excepción EOFError se genera en el proceso secundario por raw_input()
(esperaba datos pero obtuvo EOF (sin datos)).
p.stdout.read()
bloquea para siempre porque intenta leer todos los resultados del elemento secundario al mismo tiempo que el elemento secundario espera la entrada ( raw_input()
) que causa un interbloqueo.
Para evitar el interbloqueo, debe leer / escribir de forma asincrónica (por ejemplo, mediante el uso de subprocesos o seleccionar) o saber exactamente cuándo y cuánto leer / escribir, por ejemplo :
from subprocess import PIPE, Popen
p = Popen(["python", "-u", "1st.py"], stdin=PIPE, stdout=PIPE, bufsize=1)
print p.stdout.readline(), # read the first line
for i in range(10): # repeat several times to show that it works
print >>p.stdin, i # write input
p.stdin.flush() # not necessary in this case
print p.stdout.readline(), # read output
print p.communicate("n/n")[0], # signal the child to exit,
# read the rest of the output,
# wait for the child to exit
Nota: es un código muy frágil si leer / escribir no está sincronizado; es un callejón sin salida.
Tenga cuidado con el problema de bloqueo de bloques (aquí se resuelve usando el indicador "-u" que desactiva el almacenamiento en búfer para stdin, stdout en el niño ).
bufsize=1
hace que los conductos bufsize=1
en búfer de línea en el lado principal .