Ich brauche die Summe einer ganzen Zahl in mehreren Webseiten. getPages()
analysiert die ganze Zahl und setzt sie auf $subTotal
. getPages()
wird in einer for-Schleife im Hintergrund aufgerufen, aber wie bekomme ich die Summe von $subTotal
? Ist das ein Subshelling-Problem?
Das habe ich bisher versucht.
%Vor%Irgendein Rat geschätzt.
Ja, das ist ein Subshelling-Problem. Alles, was in einer ... &
-Liste (d. H. Ihre getPages $KEY $VALUE &
) ausgeführt wird, wird in einer Subshell ausgeführt, was bedeutet, dass Änderungen von Variablen dort die Eltern-Shell nicht beeinflussen.
Ich denke, man könnte etwas mit Coprozessionen (dh Kommunikation durch Streams) machen, oder vielleicht GNU parallel oder < a href="http://www.gnu.org/software/pexec/"> pexec .
Hier ist ein Beispiel mit pexec
, das die Standardausgabe verwendet, um von den einzelnen Prozessen zu kommunizieren. Ich habe einen einfacheren Befehl verwendet, da die von Ihnen aufgelisteten Server von hier aus nicht erreichbar sind. Dies zählt die Zeilen auf einigen Webseiten und fasst sie zusammen.
Wir verwenden hier einige Tricks:
<( ... )
) zusammen mit der Eingabeumleitung ( <
) anstelle einer einfachen Pipe. (( ... ))
arithmetischer Ausdruck. Ich hätte stattdessen let
verwenden können, aber dann müsste ich alles zitieren oder Leerzeichen vermeiden. (Ihre total=$(( total + subtotal ))
hätte auch funktioniert.) pexec
:
--normal-redirection
bedeutet, dass alle Ausgabeströme aus den Teilprozessen zusammen in den Ausgabestream von pexec
umgeleitet werden. (Ich bin mir nicht sicher, dass dies zu Verwirrung führen könnte, wenn zwei Prozesse gleichzeitig schreiben möchten.) --environment hostname
übergibt den abweichenden Parameter für jede Ausführung als Umgebungsvariable. Sonst wäre es ein einfaches Befehlszeilenargument. --number ${#ARRAY[*]}
(die in unserem Fall --number 4
erhält) stellt sicher, dass alle Prozesse parallel gestartet werden, anstatt nur so viele wie wir CPUs oder eine andere Heuristik haben. (Dies ist für Netzwerk-Roundtrip-gebundene Arbeit. Für CPU-gebundene oder bandbreitengebundene Sachen wäre eine kleinere Zahl besser.) --shell-command
stellt sicher, dass der Befehl von einer Shell ausgewertet wird, anstatt zu versuchen, ihn direkt auszuführen. Dies ist notwendig wegen der Pipeline dort. --parameters "${ARRAY[@]}"
listet die tatsächlichen Argumente auf - d. h. die Elemente des Arrays. Für jede von ihnen wird eine separate Version des Befehls gestartet. --
kommt der Befehl - als einzelner '
-Quote-String, um eine vorzeitige Interpretation des $hostname
dort durch die äußere Shell zu vermeiden. Der Befehl simple lädt die Datei herunter und leitet sie an wc -l
, wobei die Zeilen gezählt werden. Beispielausgabe:
%Vor% Hier ist (ein Teil davon) die Ausgabe von ps -f
, während diese ausgeführt wird:
Wir können sehen, dass wirklich alles parallel läuft, so viel wie möglich auf meinem Ein-Prozessor-System.
Tags und Links bash