Erst du, dann du, dann du, dann du
Synchronisation von Jobs in der Shell
Hier hilft der Trick, die Ausgabe jedes Jobs in Variablen zwischenzuspeichern und sie erst am Ende auszugeben. Abgesehen davon, dass alle Jobs unabhängig voneinander laufen können, lässt sich die Ausgabe nun auch in die richtige Reihenfolge bringen. Damit es übersichtlicher wird, kapselt eine Shell-Funktion den Aufruf von cat und den Job, der ich den Job als Argument übergebe:
01 in_pipe() { 02 CMD="$*" 03 BEFORE=$(date) 04 LOG=$($CMD) 05 RESULT=$? 06 AFTER=$(date) 07 08 cat 09 echo $BEFORE 10 echo "$CMD" 11 echo "-----" 12 echo "$LOG" 13 echo "-----" 14 echo "RESULT=$RESULT" 15 echo $AFTER 16 echo "=====" 17 return $RESULT 18 }
Diese Funktion zieht alle Register. Zeile 02 speichert alle übergebenen Argumente in einer Variablen, die als Befehl für den Job dient. Die Zeilen 03 und 06 notieren die Zeit vor und nach dem Aufruf des Jobs in zwei weiteren Variablen. Zeile 04 speichert die Ausgaben des Jobs in einer Shell-Variablen, während er läuft, und Zeile 05 hebt den Rückgabewert für später auf. Zeile 08 enthält den Aufruf von cat, der die Ausgabe des vorherigen Jobs durchleitet: Dadurch entspricht die Reihenfolge der Ausgaben der Reihenfolge der Jobs in der Pipe. Ab Zeile 09 kommt die Ausgabe aller gesammelten Werte des aktuellen Jobs, gefolgt von einer Trennzeile. In Zeile 17 schließlich gibt die Funktion den Rückgabewert des Jobs an die aufrufende Shell zurück.
Diese Funktion findet nun wie folgt Einsatz:
01 echo "=====" \ | in_pipe sleep 3 \ | in_pipe echo Hallo \ | in_pipe sleep 2 02 date
Die Ausgabe sieht folgendermaßen aus:
===== Mi 21. Jan 10:01:58 CET 2015 sleep 3 ----- ----- RESULT=0 Mi 21. Jan 10:02:01 CET 2015 ===== Mi 21. Jan 10:01:58 CET 2015 echo Hallo ----- Hallo ----- RESULT=0 Mi 21. Jan 10:01:58 CET 2015 ===== Mi 21. Jan 10:01:58 CET 2015 sleep 2 ----- ----- RESULT=0 Mi 21. Jan 10:02:00 CET 2015 ===== Mi 21. Jan 10:02:01 CET 2015
Alle Jobs starten also zur gleichen Zeit, werden aber zu unterschiedlichen Zeiten fertig. Das Skript fährt fort, nachdem der langsamste Job endete.