2010-10-07 4 views
5

Ich möchte ein Skript ausführen, wenn alle Aufträge, die ich an einen Server gesendet habe, erledigt sind.Wie führe ich automatisch ein Bash-Skript aus, wenn meine QSub-Jobs auf einem Server beendet sind?

zum Beispiel, ich sende

ssh server "for i in config*; do qsub ./run 1 $i; done" 

Und ich bekomme wieder eine Liste der Jobs, die gestartet wurden. Ich möchte automatisch ein anderes Skript auf dem Server starten, um die Ausgabe von diesen Jobs zu verarbeiten, sobald alle abgeschlossen sind.

Ich würde irgendwelche Ratschläge zu schätzen wissen, dass Sie mir folgende unelegant Lösung vermeiden helfen würde:

Wenn ich jeden der 1000 Job-IDs aus dem obigen Aufruf in einer separaten Datei zu speichern, ich den Inhalt jeder Datei überprüfen konnte gegen die aktuelle Liste der laufenden Aufträge, dh Ausgabe von einem Aufruf:

ssh qstat 

ich würde nur jede halbe Stunde überprüfen müssen, aber ich könnte mir vorstellen, dass es einen besseren Weg gibt.

Antwort

6

Es hängt ein wenig davon ab, welchen Job Scheduler Sie verwenden und welche Version, aber es gibt noch einen anderen Ansatz, der auch verwendet werden kann, wenn Ihre Ergebnisverarbeitung auch in derselben Warteschlange wie der Job durchgeführt werden kann.

Eine sehr praktische Möglichkeit, viele verwandte Jobs in neueren Versionen von Drehmoment (und mit Raster-Engine und anderen) zu verwalten, ist die Ausführung der einzelnen Jobs als Job-Array (vgl. http://docs.adaptivecomputing.com/torque/4-1-4/Content/topics/commands/qsub.htm#-t). Dies erfordert, dass die einzelnen Runs irgendwie auf Nummern abgebildet werden, was nicht immer praktisch ist. Aber wenn Sie es für Ihre Jobs tun können, vereinfacht dies die Verwaltung der Jobs erheblich. Sie können sie alle in einer Zeile zusammenfassen, Sie können sie alle gleichzeitig aufrufen oder speichern (wobei Sie trotzdem die Möglichkeit haben, Aufträge einzeln zu bearbeiten).

Wenn Sie dies tun, können Sie einen Analysejob übergeben, der von dem Array von Jobs abhängig ist, die nur ausgeführt werden, sobald alle Jobs im Array abgeschlossen sind: (cf. http://docs.adaptivecomputing.com/torque/4-1-4/Content/topics/commands/qsub.htm#dependencyExamples). Senden des Jobs würde wie aussehen:

qsub analyze.sh -W depend=afterokarray:427[] 

wo analysieren.sh hatte das Skript, um die Analyse durchzuführen, und 427 wäre die Job-ID des Arrays von Jobs, die Sie gestartet haben. (Das [] bedeutet nur laufen, nachdem alle abgeschlossen sind). Die Syntax unterscheidet sich für andere Scheduler (zB SGE/OGE), aber die Ideen sind die gleichen.

Um dies zu erreichen, muss man etwas tun, und Tristans Ansatz hat den Vorteil, einfach zu sein und mit jedem Scheduler zu arbeiten. aber lernen, Job-Arrays in dieser Situation zu verwenden, wenn Sie viel davon tun werden, kann Ihre Zeit wert sein.

6

Etwas, was Sie in Betracht ziehen könnten, ist jedes Jobskript einfach einen Dateinamen in einem speziellen Ordner wie $i.jobdone zu berühren, und in Ihrem Hauptskript könnten Sie einfach ls *.jobdone | wc -l verwenden, um die richtige Anzahl von Jobs zu testen.

1

Sie können warten verwenden, um die Ausführung zu stoppen, bis alle Ihre Aufträge erledigt sind. Sie können sogar alle Exit-Status und andere laufende Statistiken sammeln (Zeit, Anzahl der ausgeführten Jobs, was auch immer), wenn Sie herumfahren und auf bestimmte IDs warten.

würde ich ein kleines C-Programm schreiben das Warten und das Sammeln zu tun (wenn Sie Berechtigungen zum Hochladen und ausführbare Programme zu starten), aber Sie können leicht die bash verwenden warten eingebaut für etwa den gleichen Zweck, wenn auch mit weniger Flexibilität.

Bearbeiten: kleines Beispiel.

#!/bin/bash 

... 
waitfor='' 

for i in tasks; do 
    task & 
    waitfor="$waitfor $!" 
done 

wait $waitfor 
... 

Wenn Sie das Skript im Hintergrund laufen, wird es nicht stören und was kommt nach dem warten Linie wird ausgeführt, wenn Ihre Arbeitsplätze sind vorbei.