Comando de Python popen. Espere hasta que termine el comando


79

Tengo un script en el que lanzo con popen un comando de shell. El problema es que la secuencia de comandos no espera hasta que finalice el comando popen y continúa inmediatamente.

om_points = os.popen(command, "w")
.....

¿Cómo puedo decirle a mi secuencia de comandos de Python que espere hasta que el comando de shell haya finalizado?

Respuestas:


112

Dependiendo de cómo quiera trabajar su script, tiene dos opciones. Si desea que los comandos se bloqueen y no hagan nada mientras se ejecuta, puede usar subprocess.call.

#start and block until done
subprocess.call([data["om_points"], ">", diz['d']+"/points.xml"])

Si desea hacer cosas mientras se ejecuta o alimentar cosas stdin, puede usarlo communicatedespués de la popenllamada.

#start and process things, then wait
p = subprocess.Popen([data["om_points"], ">", diz['d']+"/points.xml"])
print "Happens while running"
p.communicate() #now wait plus that you can send commands to process

Como se indica en la documentación, se waitpuede interbloquear, por lo que es recomendable comunicarse.


Consulte los documentos en subprocess.call
thornomad

Si bien el subproceso se prefiere en muchas respuestas, no puede manejar muy bien el espacio y la cuota dentro del comando. La respuesta anterior no resuelve directamente la pregunta de os.popen.
Chang

el subproceso puede ser hasta 2 veces
MonsieurBeilto

subprocess.run()se agregó en Python 3.5 y es "El enfoque recomendado para invocar subprocesos"
LoMaPh

29

Puede utilizar subprocesspara lograr esto.

import subprocess

#This command could have multiple commands separated by a new line \n
some_command = "export PATH=$PATH://server.sample.mo/app/bin \n customupload abc.txt"

p = subprocess.Popen(some_command, stdout=subprocess.PIPE, shell=True)

(output, err) = p.communicate()  

#This makes the wait possible
p_status = p.wait()

#This will give you the output of the command being executed
print "Command output: " + output

El subproceso puede ser hasta 2 veces más lento que el sistema operativo
MonsieurBeilto

12

Obligar popena no continuar hasta que se lea toda la salida haciendo:

os.popen(command).read()

2
No soy un experto en Python, pero esta parece ser la solución más simple que hace la menor cantidad de modificaciones al código original. ¿Alguna razón por la que esta no sería una buena solución?
jdmcnair

7

Deja que el comando que intentas pasar sea

os.system('x')

luego lo convertiste en una declaración

t = os.system('x')

ahora, Python estará esperando el resultado de la línea de comandos para poder asignarlo a la variable t.


4

Lo que buscas es el waitmétodo.


Pero si escribo: om_points = os.popen (data ["om_points"] + ">" + diz ['d'] + "/ points.xml", "w"). Wait () Recibo este error: Traceback (última llamada más reciente): Archivo "./model_job.py", línea 77, en <module> om_points = os.popen (data ["om_points"] + ">" + diz ['d'] + "/ points .xml "," w "). wait () AttributeError: el objeto 'file' no tiene atributo 'wait' ¿Cuál es el problema? Gracias de nuevo.
michele

12
No hizo clic en el enlace que proporcioné. waites un método de la subprocessclase.
Olivier Verdier

1
esperar puede interbloqueo si el proceso escribe en stdout y nadie lo lee
ansgri

El subproceso puede ser hasta 2 veces más lento que el sistema operativo
MonsieurBeilto

2

wait () funciona bien para mí. Los subprocesos p1, p2 y p3 se ejecutan al mismo tiempo. Por lo tanto, todos los procesos se realizan después de 3 segundos.

import subprocess

processes = []

p1 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)
p2 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)
p3 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)

processes.append(p1)
processes.append(p2)
processes.append(p3)

for p in processes:
    if p.wait() != 0:
        print("There was an error")

print("all processed finished")

El subproceso puede ser hasta 2 veces más lento que el sistema operativo
MonsieurBeilto

0

Creo que process.communicate () sería adecuado para una salida de tamaño pequeño. Para una producción mayor, no sería el mejor enfoque.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.