2010-03-23 6 views
10

Ich habe mit diesem als Referenz, aber nicht in der Lage, genau zu erreichen, was ich brauche: Calling an external command in PythonAsynchrone Hintergrundprozesse in Python?

Ich lese auch dies: http://www.python.org/dev/peps/pep-3145/

Für unser Projekt haben wir 5 SVN Kassen, die aktualisieren müssen bevor wir unsere Anwendung bereitstellen können. In meiner Entwicklungsumgebung, in der schnelle Bereitstellungen ein wenig wichtiger für die Produktivität sind als eine Produktionsbereitstellung, habe ich daran gearbeitet, den Prozess zu beschleunigen.

Ich habe ein Bash-Skript, das anständig funktioniert hat, aber einige Einschränkungen hat. Ich feuern mehrere ‚svn updates‘ mit dem folgenden Bash-Befehl:

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

Diese alle parallel laufen und es funktioniert ziemlich gut. Ich benutze dieses Muster auch im Rest des Build-Skripts, um jeden Ameisen-Build abzufeuern und dann die Kriege nach Tomcat zu verschieben.

Ich habe jedoch keine Kontrolle über das Stoppen der Bereitstellung, wenn eines der Updates oder ein Build fehlschlägt.

Ich schreibe mein Bash-Skript mit Python um, damit ich mehr Kontrolle über die Zweige und den Deployment-Prozess habe.

Ich benutze subprocess.call(), um die 'svn update/repo' Befehle abzufeuern, aber jeder agiert sequentiell. Ich versuche '(svn update/repo) &' und diese alle feuern ab, aber der Ergebniscode kehrt sofort zurück. Ich habe also keine Möglichkeit festzustellen, ob ein bestimmter Befehl im asynchronen Modus fehlschlägt oder nicht.

import subprocess 

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

Ich würde gerne einen Weg finden, Python Feuer aus jedem Unix-Befehl zu haben, und wenn eine der Anrufe nicht das gesamte Skript stoppt jederzeit.

Antwort

18

Verwenden Sie nicht shell=True. Es wird unnötig rufen Sie die Shell, um Ihre svn Programm aufrufen, und das wird Ihnen die Rückkehr der Shell-Code anstelle von Svn geben.

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

Das ist genau das, was ich gesucht habe. – Geuis

+1

Danke, es funktioniert. Gibt es eine Möglichkeit Subprozess im Hintergrund auszuführen - jetzt im Terminal angezeigt? (Zur Zeit sehe ich geöffnete Shell mit Arbeitsbefehl) –