GNU parallel: leiten Sie alle stdin an alle Prozesse weiter

677
Mr. Wonko

Ich versuche, die Eingaben auf unterschiedliche Weise parallel zu verarbeiten und die resultierenden Zeilen so zu schreiben, wie sie hereinkommen. Mein derzeitiger Ansatz lautet:

# process_parallel.sh read input parallel --colsep ' ' --linebuffer 'echo $input | {}' \ ::: 'python process1.py' ./process2.sh ./process3 

Der Kontext läuft auf etwas wie folgt aus:

(sleep 1; echo "short input arriving late") | ./process_parallel.sh | ./collate_results.sh 

Das obige funktioniert, hat aber einen wichtigen Nachteil: Die Prozesse werden erst gestartet, wenn die Eingabe gelesen wurde. Ich möchte sie sofort starten, da dies eine Weile dauern kann, dann habe ich zu jedem von ihnen parallele Pfeifen.

Wie kann ich das erreichen?

2

2 Antworten auf die Frage

1
Ole Tange

In GNU Parallel wurde bereits einiges getan, um einen neuen Job nicht zu starten, es sei denn, es gibt Daten für die Ausführung. Dies liegt daran, dass einige Programme hart ausfallen, wenn sie keine Eingaben erhalten. Sie arbeiten also gegen das Design von GNU Parallel.

Um die Eingabe zu duplizieren, können Sie die teeErsetzung verwenden und bearbeiten:

cat namedpipe_or_file | tee >(process1) >(process2) >(process3) >/dev/null 

Es beginnt process1, process2und process3sofort. Die Ausgabe kann jedoch gemischt werden. Wenn die Ausgabe verwendet werden muss, sollten Sie sie in andere Dateien umleiten:

cat namedpipe_or_file | tee >(process1 > out1) >(process2 > out2) >(process3 > out3) >/dev/null 
0
MariusMatutiae

Verfügen Sie über zwei Wrapper-Skripts: Ändern Sie zunächst die Datei process_parallel.sh so, dass jeder der Prozesse aufgefordert wird, seine Eingabe aus drei Dateien zu lesen, z. B. file1, file2, file3.

Schreiben Sie nun ein zweites Wrapper-Skript, das parallel die Standardeingabe an die drei Dateien sendet, etwa:

 #!/bins/bash #parallelise input # let's call this file parallelise parallel -j 3 -- "echo $1 > file1" "echo $1 > file2" "echo $1 file3" 

Jetzt fängst du deine Sachen an mit:

 ./process_parallel_sh; cat InputFile | parallelise; 
Das ist akzeptabel, obwohl ich anstelle von tatsächlichen Dateien Named Pipes verwenden würde. Aber ich habe auf einen einfacheren Weg gehofft ... Ich vermute, Parallel macht einfach nicht das, was ich brauche. Mr. Wonko vor 8 Jahren 0