GNU "parallel --pipe" verarbeitet stdin nicht zeilenweise

528
ThorSummoner

Ich bin total verwirrt, wie man GNU parallel verwendet, um stdin an den Jobbefehl zu übergeben.

Ich habe, was ich mir vorstellte, ein wirklich üblicher Anwendungsfall. Ich habe einen Prozess xxd, der etwas mit stdin macht und stdout ausgibt. Ich habe zum Beispiel eine Möglichkeit, einen anderen Standard-Stream zu erstellen oder Arbeit zu erhalten seq 3, und ich kann die beiden kombinieren und ein improvisiertes Werkzeug wie folgt erstellen:

$ seq 3 | while read line; do echo $line | xxd; done 00000000: 310a 1. 00000000: 320a 2. 00000000: 330a 3. 

Großartig. Wir können deutlich sehen, dass jeder Aufruf von xxdeine Zeile bekommt und eine nachfolgende Zeile angehängt wird.

Dies ist, was Pipe paralleltun:

$ seq 3 | parallel --pipe --recend="\n" -L 1 xxd ...  00000000: 310a 320a 330a 1.2.3. 

parallel --pipeNimmt alles von stdin und schickt es an einen Aufruf, der xxdmich verwirrt, weil alle dokumentierten Parameter und ihre --recend="\n"Standardeinstellungen diesem Verhalten zu widersprechen scheinen: (Standardeinstellung) Jobs durch Newline abgrenzen, -L 1(Standardeinstellung) sendet maximal eine Zeile an den Befehl .

Null-Separatoren haben das gleiche Problem. Sie werden auch wörtlich weitergegeben:

seq 3 | tr '\n' '\0' | parallel --null --pipe xxd ...  00000000: 3100 3200 3300 1.2.3. 

Eine Erklärung für dieses Verhalten wäre wünschenswert, zumal diese Parameter speziell für den --pipeModus von zu gelten scheinen parallel.

2

2 Antworten auf die Frage

2
Ole Tange

Du bist so nah. -Lsetzt die Rekordgröße (in Zeilen), aber nicht, wie viele Datensätze gesendet werden soll. Dies wird gesteuert durch -N. Voreinstellung --recendist \nalso nicht erforderlich. Die Standardeinstellung -List 1, sodass diese nicht benötigt wird.

seq 3 | parallel --pipe -N 1 xxd 
1
ThorSummoner

Hinweis: Dies ist meine ursprüngliche Problemumgehung. Es ist ziemlich hässlich und der akzeptierten Antwort unterlegen . Ich lasse es aber aus pädagogischen Gründen intakt.

Der Trick besteht darin, den Pipe-Modus nicht zu verwenden und Echo (oder ähnliches) zu verwenden, um Ausführungsdateien pro Job in stdout umzuwandeln:

$ seq 3 | parallel "echo {} | xxd" 00000000: 310a 1. 00000000: 320a 2. 00000000: 330a 3. 
Gut gemacht. Upvoted für den Wissensaustausch auf diese Weise. Kamil Maciorowski vor 5 Jahren 0