einen Befehl für jede Zeile von stdin sofort ausführen?

993
VasyaNovikov

Wie führe ich einen Befehl für jede Zeile stdinsofort aus?

Beispiel :

(echo abc; sleep 10; echo def;) | ??? 

Das xargsTool führt den Job nicht aus, da es blockiert, bis alle Daten sichtbar sind (wartet, bis stdout geschlossen wird). Ich muss jedoch sofort Befehle ausführen, wenn neue Zeilen verfügbar werden.

3
http://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe könnte interessant sein. Hennes vor 8 Jahren 1
@Hennes Danke. Leider hilft es nicht. Das Problem liegt nicht in der Pipe, sondern in der Art und Weise, wie `xargs` funktioniert (es wartet / blockiert, bis es alle Eingaben sieht). VasyaNovikov vor 8 Jahren 0
Verwenden Sie also keine xargs. Übergeben Sie die ungepufferte Ausgabe durch eine Pipe, und verwenden Sie am anderen Ende der Pipe ein Shell-Skript, um Zeilen bis zum EOF zu lesen. Hennes vor 8 Jahren 1
@Hennes Ich suche ein Befehlszeilenprogramm, das dies für mich tun würde. VasyaNovikov vor 8 Jahren 0
@Hennes Ich habe eine Beispielantwort geschrieben, um die Idee hinter deinen Kommentaren zu verstehen. VasyaNovikov vor 8 Jahren 1

2 Antworten auf die Frage

2
Ole Tange

Verwenden von GNU Parallel:

(echo abc; sleep 10; echo def;sleep 10; echo def;)|parallel -uj1 

-u wird benötigt, um die Ausgabe sofort abzurufen. Ohne wird der Befehl ausgeführt, die Ausgabe wird jedoch erst später gedruckt.

-j1 erzwingt die Ausführung eines einzelnen Jobslots. Wenn Sie dies nicht angeben, liest GNU Parallel vor dem Start n Jobs, wobei n die Anzahl der Kerne ist.

Whoa, das hat den Trick gemacht! Ich habe "parallel -u echo" ausprobiert, aber, wie Sie sagten, "-j1" war notwendig. VasyaNovikov vor 8 Jahren 0
1
VasyaNovikov

Verwenden eines Shell-Skripts wie von @Hennes vorgeschlagen:

long_running_command | ( while read -r LINE; do echo $LINE; command_to_execute "$LINE"; done; )