2010-03-23 6 views
10

He estado usando esto como una referencia, pero no es capaz de lograr exactamente lo que necesita: Calling an external command in PythonProcesos de fondo asincrónicos en Python?

También estaba leyendo esto: http://www.python.org/dev/peps/pep-3145/

Para nuestro proyecto, tenemos 5 cajas SVN que necesitan actualizar antes de que podamos implementar nuestra aplicación. En mi entorno de desarrollo, donde las implementaciones rápidas son un poco más importantes para la productividad que una implementación de producción, he estado trabajando para acelerar el proceso.

Tengo un script bash que ha estado funcionando decentemente, pero tiene algunas limitaciones. Me fuego hasta múltiples 'svn actualizaciones' con el siguiente comando bash:

(svn update /repo1) & (svn update /repo2) & (svn update /repo3) & 

Estos todos corren en paralelo y funciona bastante bien. También utilizo este patrón en el resto del script de compilación para disparar cada build de hormiga, y luego mover las guerras a Tomcat.

Sin embargo, no tengo control sobre la detención de la implementación si falla una de las actualizaciones o una compilación.

Estoy volviendo a escribir mi script bash con Python, así que tengo más control sobre las sucursales y el proceso de implementación.

Estoy utilizando subprocess.call() para activar los comandos 'svn update/repo', pero cada uno actúa de forma secuencial. Intento '(svn update/repo) &' y todos se disparan, pero el código de resultado vuelve inmediatamente. Así que no tengo manera de determinar si un comando en particular falla o no en el modo asíncrono.

import subprocess 

subprocess.call('svn update /repo1', shell=True) 
subprocess.call('svn update /repo2', shell=True) 
subprocess.call('svn update /repo3', shell=True) 

Me encantaría encontrar una manera de tener el fuego fuera del pitón de cada comando de Unix, y si alguna de las llamadas falla en cualquier momento se detiene todo el guión.

Respuesta

18

No utilice shell=True. Inútilmente invocará el shell para llamar a su programa svn, y eso le dará el código de retorno del shell en lugar de svn.

repos = ['/repo1', '/repo2', '/repo3'] 
# launch 3 async calls: 
procs = [subprocess.Popen(['svn', 'update', repo]) for repo in repos] 
# wait. 
for proc in procs: 
    proc.wait() 
# check for results: 
if any(proc.returncode != 0 for proc in procs): 
    print 'Something failed' 
+2

Eso es justo lo que estaba buscando. – Geuis

+1

Gracias, funciona. ¿Hay alguna forma de ejecutar un subproceso en segundo plano, ahora se muestra en la terminal? (Actualmente veo shell abierto con comando de trabajo) –

Cuestiones relacionadas