GNU Parallel-Nutzung – wie wird die aktuell übergebene Zeichenfolge parallelisiert?

GNU Parallel-Nutzung – wie wird die aktuell übergebene Zeichenfolge parallelisiert?

Ich verwende GNU Parallel und möchte verstehen, wie ich die einzelnen Zeichenfolgen an jeden Parallel-Befehl übergeben kann.

Als Beispiel,GNU Parallel-Dokumentationzeigt, wie Dateien vom aktuellen Verzeichnis in ein anderes verschoben werden:

ls | parallel mv {} destdir

Gibt es also eine Möglichkeit, jede parallel übergebene Datei einzeln abzurufen/drucken?

Fall für parallele Verarbeitung

Ich muss parallel mehrere Standorte prüfen und aufzeichnen

  • http-Rückgabecode (2xx, 4xx, 5xx)
  • Die Quell-URL
  • Die endgültige Ziel-URL
  • der Curl-Exitcode

Hier ist der Code, der dies bewirkt:

    unset return_code_array
    unset destination_url_array
    unset exit_code_array

    while read -r return_code_var destination_url_var exit_code_var; do

        destination_url_array+=("$destination_url_var")
        exit_code_array+=("$exit_code_var")
        return_code_array+=("$return_code_var")

    done < <(printf '%s\n' "${all_valid_URLs_array[@]}" | parallel -j 20 -k 'curl --max-time 20 -sL -o /dev/null -w "%{response_code} %{url_effective} " {}; printf "%s %s\n" "$?" ')

Als Ergebnis habe ich drei Arrays und sie enthalten den HTTP-Rückgabecode, die endgültige Ziel-URL und den Curl-Exitcode-Status für jede entsprechende Zeile der all_valid_URLs_arrayEinträge. Gleichzeitig muss ich für jedes Array einige Verarbeitungsvorgänge durchführen destination_url_var– beispielsweise vergleichen, ob es mit der Quell-URL übereinstimmt, habe aber keine Ahnung, wie ich die Zeichenfolge abrufen kann, die an Parallels übergeben wurde.

Derzeit führe ich für eine solche Verarbeitung eine zweite Schleife nach der obigen aus, möchte aber wissen, ob dies möglich ist.

Danke.

Antwort1

In Ihrem Beispiel 'curl … {}; printf "%s %s\n" "$?" '(warum das zweite %s?) handelt es sich um einen in einfache Anführungszeichen gesetzten Shell-Code. Darin können Sie {}mehr als einmal verwenden:

curl … {}; printf "%s %s\n" "$?" {}

Alternativ können Sie eine Variable erstellen und sie so oft verwenden, wie Sie möchten. Der Name der Variable kann beschreibend sein, das ist ein Vorteil. Es gibt noch einen weiteren Vorteil: Im Allgemeinen {}kann es sich bei dem, was ersetzt wird, um eine lange Zeichenfolge handeln. Häufiges Ersetzen kann den Code aufblähen, der parallelan bestimmte Shells weitergegeben wird. Meiner Meinung nach ist es besser, einmal zu ersetzen und die Shell die Zeichenfolge speichern und wiederverwenden zu lassen:

source_URL={}; curl … "$source_URL"; printf "%s %s\n" "$?" "$source_URL"

Im Falle von GNU parallelist das Einbetten {}in den Shell-Code sicher. Es handelt sich um eine Ausnahme, die in dieser Antwort ausdrücklich erwähnt wird:Niemals {}in den Shellcode einbetten!. Das wissen Sie wahrscheinlich schon, die Bemerkung richtet sich an ein allgemeines Publikum.

readBeachten Sie, dass Sie Ihre in der Hauptschleife anpassen müssen , es muss jetzt lesen invierVariablen. Auf diese Weise übertragen Sie die Quell-URL von innen parallelin die Hauptschleife, wo Sie sie vergleichen destination_url_varoder damit machen können, was Sie wollen.

Dennoch wird bei diesem Ansatz „was auch immer Sie wollen“ nicht parallelisiert.

Wenn Sie die Ausgabe von curlin separate Variablen innerhalb des von ausgeführten Shell-Codes erfassen parallel(anstatt sie nur zum Erfassen außerhalb von auszugeben parallel), können Sie Vergleiche durchführen (oder was immer Sie wollen).Dort, parallel. Und zBprintf bedingt. Es bleibt Ihnen überlassen, wo Sie die gewünschte Logik implementieren, solange das Innere eine parallelAusgabe in der von außen erwarteten Form erzeugt read.

Der übergebene Shell-Code parallelmuss immer noch in einfache Anführungszeichen gesetzt werden. Wenn er wächst, müssen Sie möglicherweise in genau diesem Code einfache Anführungszeichen verwenden (einbetten); dann wird das Anführen etwas komplizierter und weniger lesbar. Erwägen Sie in einer solchen Situation, den Code in ein separates Skript zu verschieben, wo Sie unabhängig Anführungszeichen setzen können. Sie rufen es vom Hauptskript aus folgendermaßen auf:

while read … ; done < <( … | parallel -j 20 -k 'path/to/separate_script {}' )

Innerhalb der wird separate_scriptdie ersetzte Zeichenfolge {}verfügbar sein als $1(vergessen Sie nicht,Setzen Sie doppelte Anführungszeichen).

verwandte Informationen