Hallo Thomas, hallo Leute, Am Donnerstag, 28. Januar 2010 schrieb Thomas Michalka:
# Alle Backups parallel laufen lassen for SRC_DIR in $SRC_DIR_LIST ; do rsync <options> $SRC_DIR $DEST_DIR & PID_LIST="$! " done
# Jetzt aber auf den Abschluss aller Backups warten wait $PID_LIST exit_status=$?
# Der Rest des Skripts kommt hier ...
Was aber passiert, wenn man in einer weiteren Schleife die Rückgabewerte aller rsync-Prozesse ermittelt, etwa so:
for PID in $PID_LIST ; do wait $PID exit_status_list="$? " done
Hier zweifle ich stark, ob das überhaupt funktioniert, denn
1. Hier wird der Sinn der oben gewollten Asynchronität der Hintergrundjobs konterkariert, weil für eine PID, deren Prozess noch nicht terminiert ist, in dieser for-Schleife gewartet wird, bis er beendet ist.
Wäre in Deinem Fall ja nicht wirklich ein Problem, wenn ich die Kommentare in Deinem Script ("Jetzt aber auf den Abschluss aller Backups warten") richtig interpretiere. Unschön ist es trotzdem.
2. Es ist nicht klar, ob wait $PID bei einem vor der for-Schleife schon beendeten Job noch den exit_status zurückgibt und was demnach in der exit_status_list landet.
Teste das doch einfach selbst ;-) # true & [1] 16758 [1]+ Fertig true # false & [1] 16760 [1]+ Exit 1 false # wait 16758 # echo $? 0 # wait 16760 # echo $? 1 -> ja, die Bash merkt sich den Exitcode ihrer Kindprozesse. Ich hab noch was interessantes in der Bash-manpage gefunden: Any trap on SIGCHLD is executed for each child that exits. Die Hintergrundprozesse können sich also per Callback melden, wenn sie fertig sind ;-) Ich weiß nicht, ob da die PID irgendwie mitgeliefert wird, aber immerhin könntest Du damit einen Zähler a la "noch 3 Kindprozesse" bauen. (Weiter unten hab ich Dir auch noch ein besseres Callback notiert.)
Willkommen wäre mir ein Hinweis, wo man solche grundlegenden Bash-Programmier-Fragen und -Lösungen nachschlagen kann.
Nunja, sowas wie Deine Frage würde ich nicht als "grundlegende Bash- Programmier-Frage" einstufen ;-) Ich habe dazu auch noch die interessante Aufgabenstellung "Variablen aus der Subshell"[1] in Erinnerung. Vielleicht kannst Du ja mit einem zusätzlichen Ausgabekanal, auf dem die Hintergrundprozesse schreiben, was anfangen (keine Ahnung, wie sich meine Tricks mit Hintergrundprozessen vertragen - ich habe das nie getestet). So, und jetzt die pragmatische Lösung: verwende eine andere Methode zur Erkennung, welche Prozesse noch laufen ;-) Eine Variante wäre beispielsweise, pro Prozess ein Tempfile[2] mit dem Exitcode anzulegen: for SRC_DIR in $SRC_DIR_LIST ; do { rsync <options> $SRC_DIR $DEST_DIR ; echo $? > tmp_$SRC_DIR ; # [2] }& PID_LIST="$! " Damit schlägst Du ein paar Fliegen mit einer Klappe: - Du siehst, wann ein Prozess fertig ist: test -f tmp_irgendwas && echo "fertig" - Im Tempfile steht der Exitcode, den Du problemlos einem Prozess (wichtiger: einem Backup-Verzeichnis) zuordnen kannst - Du kannst problemlos über alle Prozesse/Tempfiles einen Loop machen, ohne irgendwie geblockt zu werden ("test -f" oder "test -s") - Wenn alle angefragten Tempfiles existieren und jeweils eine "0" enthalten, ist das Backup komplett und erfolgreich ;-) Noch eine Variante ohne Tempfiles: Bau Dir selbst ein Callback ;-) Das ist besser als SIGCHLD, weil Du damit den Exitstatus und z. B. das gesicherte Verzeichnis durchreichen kannst. Bei der Gelegenheit kannst Du auch gleich ein Logfile schreiben usw. - die Lösung ist flexibel ;-) function child_finished() { echo "Status: $1" echo "Dir: $2" return $1 # exit-Status durchreichen, damit er z. B. für wait # sichtbar wird } for SRC_DIR in $SRC_DIR_LIST ; do { rsync <options> $SRC_DIR $DEST_DIR ; child_finished $? $SRC_DIR } & So, das sollten genug Anregungen für heute Nacht sein. Wie Du siehst, hat Programmierung auch immer ein Stück weit mit Kreativität zu tun ;-) Gruß Christian Boltz [1] www.cboltz.de/de/linux/bash/ [2] dass das Ganze innerhalb eines "mktemp -d"-Verzeichnisses ablaufen sollte, versteht sich von selbst, oder? --
Kann mir bitte jemand das Script für die Abmeldung von dieser Liste schicken. ist schon wieder der erste April?? [> Josef Schwendt und Andreas Kyek in suse-linux] -- To unsubscribe, e-mail: opensuse-programming-de+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming-de+help@opensuse.org