Bash-Skript 'while-Lese' Schleife verursacht 'Pipe-Fehler', wenn er mit GNU Parallel ausgeführt wird

2034
Joe White

Laut der GNU Parallel-Mailingliste handelt es sich hierbei nicht um ein GNU Parallel-spezifisches Problem. Sie schlugen vor, dass ich mein Problem hier poste.

Der Fehler, den ich erhalte, ist ein Fehler in Bezug auf "Pipe gebrochen", aber ich denke, ich sollte zuerst den Kontext meines Problems und die Ursachen dieses Fehlers erklären. Dies geschieht, wenn Sie versuchen, ein Bash-Skript in GNU Parallel zu verwenden, das eine While-Read-Schleife enthält.

Ich habe ein einfaches bash-Skript wie folgt:

#!/bin/bash # linkcheck.sh  while read domain do host "$domain" done 

Nehmen wir an, ich möchte eine große Liste einschicken (sagen wir 250 MB).

cat urllist | ./linkcheck.sh 

Das Ausführen des Hostbefehls für URLs im Wert von 250 MB ist ziemlich langsam. Um die Sache zu beschleunigen, möchte ich die Eingabe in Blöcke aufteilen, bevor sie weitergeleitet wird, und dann mehrere Jobs parallel ausführen. GNU Parallel ist dazu in der Lage.

cat urllist | parallel --pipe -j0 parallel ./linkcheck.sh {} 

{} wird zeilenweise durch den Inhalt der Liste ersetzt. Nehmen Sie an, dass die Standardeinstellung meines Systems 500ish-Jobs pro Instanz von Parallel ausführen kann. Um diese Einschränkung zu umgehen, können Sie Parallel selbst parallelisieren:

cat urllist | parallel -j10 --pipe parallel -j0 ./linkcheck.sh {} 

Dadurch werden 5000'ish-Jobs ausgeführt. Leider wird auch der Fehler "Pipe gebrochen" (bash FAQ) verursacht . Das Skript beginnt jedoch zu funktionieren, wenn ich die while-Leseschleife entferne und Eingaben direkt von dem übernehme, was in {} eingespeist wird, z.

#!/bin/bash # linkchecker.sh  domain="$1" host "$1" 

Warum funktioniert es nicht mit einer while-Leseschleife? Ist es sicher, das SIGPIPE-Signal einfach auszuschalten, um die Meldung "Pipe gebrochen" zu stoppen, oder hat dies Nebenwirkungen wie Datenverfälschung?

Danke fürs Lesen.

2

2 Antworten auf die Frage

1
Scott

Also

Katzenliste | parallel --pipe -j0 parallel ./linkcheck.sh {} 

richtig arbeiten Ich glaube, ein Teil Ihres Problems könnte darin bestehen, dass Sie den zweiten --pipeweggelassen haben

Katzenliste | parallel -j10 --pipe parallel -j0 --pipe ./linkcheck.sh {} 

 


Übrigens musst du nie sagen

cat one_file | some_command 

Sie können dies jederzeit ändern

some_command < one_file 

was zu einem Prozess weniger (und einer Leitung weniger) führt. (Möglicherweise ist es angebracht / notwendig, catwenn Sie mehrere Eingabedateien haben.)

Vielen Dank. Die zweite Pipe zu verpassen, war mein Problem. Ich hätte schwören können, dass ich das schon probiert habe, aber offensichtlich nicht. Joe White vor 11 Jahren 0
@Joe: Wenn Sie `--pipe` verwenden, vermute ich, dass` {} `unnötig ist / ignoriert wird. Scott vor 11 Jahren 1
0
Nicole Hamilton

It appears to me that error may be arising because of a bad race condition because of the window between forking a child to run another copy of linkcheck.sh while the pipe is still open and when the child actually tries to read. In that window, another copy has read EOF and the pipe has closed.

Ja, ich glaube du hast recht. Danke für deinen Beitrag. Joe White vor 11 Jahren 0