Mehrere Unix-Pipes funktionieren nicht

878
Sridhar-Sarnobat

Diese erste Pipeline funktioniert gut (Druck "c"):

echo "a" | sed 's/a/b/' | sed 's/b/c/' 

Dieser tut nicht das, was ich erwarte (nichts wird gedruckt, wenn ich ein "a" in meine FIFO einfüge):

mkfifo fifo; cat fifo | sed 's/a/b/' | sed 's/b/c/'  

Wenn ich jedoch den zweiten "sed" -Befehl aus der letzteren Pipeline entferne, bekomme ich ein "b" gedruckt. Ich denke, mein Verständnis von Pipes und Weiterleitungen muss zu einfach sein. Kann mir jemand erklären, wie ich den zweiten Fall korrigieren kann, damit ich zwei aufeinanderfolgende Befehle für den Inhalt des FIFO ausführen kann?

(Beachten Sie, dass dies kein fifo-spezifisches Problem ist. Das gleiche Verhalten tritt auch bei netcat auf. Ich habe eine ähnliche Frage zu netcat gestellt, aber keine Antworten erhalten.)

7
Ihr Code funktioniert für mich. Vielleicht könnten Sie detaillierter beschreiben, wie Sie ein "A" in Ihr FIFO einführen. John1024 vor 9 Jahren 2
Wie @ John1024 sagte, [WorksForMe] (http://i.stack.imgur.com/VNrxB.png). Bob vor 9 Jahren 0
Ich auch, überhaupt kein Problem. MariusMatutiae vor 9 Jahren 0
"echo" a "> fifo" Sridhar-Sarnobat vor 9 Jahren 0
Es scheint, dass dies mit der Pufferung zusammenhängt. Welche Version von Sed verwendest du? Mein ist "GNU sed Version 4.2.1" Sridhar-Sarnobat vor 9 Jahren 0
@ Sridhar-Sarnobat 4.2.2 hier. Bereitgestellt aus dem Paket `sed`, Version` 4.2.2-4ubuntu1 '. Möglicherweise hängt dies jedoch auch damit zusammen, wie der Produzent (`echo` / die von Ihnen verwendete Shell) seinen Ausgabestrom spült, und nicht der Consumer (sed). Bob vor 9 Jahren 0

1 Antwort auf die Frage

8
Volker Siegel

Verwenden Sie die Option -u( --unbuffered) von sed, damit die Ausgabe geschrieben wird, anstatt sie zuerst für ein schnelles, umfangreiches Schreiben zu sammeln.

cat fifo | sed -u 's/a/b/' | sed -u 's/b/c/'

cat ist immer ungepuffert.

Wenn es nicht um etwas geht sed, sondern um ein Programm mit Ausgabepufferung, aber ohne Optionen zum Deaktivieren, gibt es Tools, mit denen die Pufferung deaktiviert werden kann - siehe man unbufferund man stdbuf.

Wenn es sich um ein Shellskript handelt, sollte es standardmäßig nicht gepuffert werden: Wenn ein Befehl eine Ausgabe im Skript erstellt und beendet, wird die Ausgabe geleert. Andernfalls verwenden Sie im Shell-Skript Unbuffer.

Hintergrundinformationen finden Sie in dieser Übersicht über die stdio-Pufferung .

Angenommen, ich hatte statt Sed ein eigenes Skript. Was würde ich in diesem Fall tun, um die Pufferung zu vermeiden? Oder sollte es standardmäßig ungepuffert sein? Sridhar-Sarnobat vor 9 Jahren 0
Nur ein paar weitere Folgen - wenn ich reguläre Perl-Ausdrücke mit Zwischenspeichern verwenden wollte, würde es so etwas wie `nc -k -l 4458 | sein perl -ne's g; $ | ++; print $ _ '| perl -ne's g; $ | ++; drucke $ _ '` Sridhar-Sarnobat vor 9 Jahren 0
Ja, was meinst du Gibt es ein Problem oder ist es ein Beispiel? Oh, und Sie können `ssed -R` verwenden, wenn Sie` sed` mit regulären Ausdrücken von Perl mögen. Volker Siegel vor 9 Jahren 0
Sorry, das war keine Frage. Ich entschuldige mich dafür, dass ich nicht klar war, es war nur ein weiteres Beispiel für dasselbe Konzept. Leider ist es für mich zu spät, diesen Kommentar zu bearbeiten. Ich wusste nicht, dass Sed Perl Regex verstehen konnte. Vielleicht sollte ich von jetzt an stattdessen damit anfangen. Sridhar-Sarnobat vor 9 Jahren 0
Oh kein Problem! Volker Siegel vor 9 Jahren 0