Bash: Prozesssubstitution und stdin


13

Die folgende Zeile ist offensichtlich:

echo "bla" | foo | bar

Aber machen die folgenden dasselbe?

echo "bla" | bar <(foo)
echo "bla" | bar < <(foo)

Welcher von den foound barlas "bla" von stdin und warum?

Ich meine, dass ich es natürlich einfach codieren und überprüfen kann, aber ich bin mir nicht sicher, ob es ein definiertes Verhalten ist oder ob ich Funktionen ausnutze, auf die ich mich nicht verlassen sollte.

Antworten:


9

Das ist shellabhängig und nicht AFAICS dokumentiert. In kshund teilen sich bashim ersten Fall foodie gleichen Werte wie bar. Sie werden für die Ausgabe von kämpfen echo.

So zum Beispiel in,

$ seq 10000 | paste - <(tr 1 X)'
1       X
2       X042
3       X043
4       X044
5       X045
[...]

Sie sehen Beweise, pastedie jeden anderen Textblock aus seqder Ausgabe trlesen, während die anderen gelesen werden.

Mit zshruft es das äußere stdin ab (es sei denn, es ist ein Terminal und die Shell ist nicht interaktiv. In diesem Fall wird sie umgeleitet von /dev/null). ksh(woher es stammt) zshund bashsind die einzigen Bourne-ähnlichen Shells mit Unterstützung für die Prozesssubstitution AFAIK.

In zu echo "bla" | bar < <(foo)beachten , dass bars stdin wird das Rohr durch den Ausgang der gespeist werden foo. Das ist gut definiertes Verhalten. In diesem Fall scheint es so, fooals sei stdin die Pfeife, von der echoin all ksh, zshund gespeist wird bash.

Wenn Sie ein konsistentes Verhalten für alle drei Shells haben und zukunftssicher sein möchten, da sich das Verhalten möglicherweise ändert, da es nicht dokumentiert ist, würde ich Folgendes schreiben:

echo bla | { bar <(foo); }

Um sicher zu gehen foo, ist stdin auch die Pipe von echo(ich kann nicht verstehen, warum du das machen möchtest). Oder:

echo bla | bar <(foo < /dev/null)

Um sicherzustellen , dass foosie nicht aus dem Rohr aus lesen echo. Oder:

{ echo bla | bar 3<&- <(foo <&3); } 3<&0

Um foo's stdin das äußere stdin wie in aktuellen Versionen von zu haben zsh.


"In diesem Fall ist foo's stdin die Pfeife, die durch Echo in ksh, zsh und bash gespeist wird." Sie haben das gerade von Hand getestet, oder ist es irgendwo dokumentiert?
Etam1024

Verweist "im ersten Fall" in der ersten Zeile auf "|" foo | bar` oder `| bar <(foo) `?
Volker Siegel

4

echo "bla" | foo | bar: Die Ausgabe von echo "bla"wird an umgeleitet foo, deren Ausgabe an umgeleitet wird bar.

echo "bla" | bar <(foo): Das leitet die Ausgabe von echo "bla"an bar. Wird baraber mit einem Argument ausgeführt. Das Argument ist der Pfad zum Dateideskriptor, an den die Ausgabe von foogesendet wird. Dieses Argument verhält sich wie eine Datei, die die Ausgabe von enthält foo. Das ist also nicht dasselbe.

echo "bla" | bar < <(foo): Man kann davon ausgehen, dass die Ausgabe von an echo "bla"gesendet werden soll barund die gesamte Anweisung der ersten entspricht. Aber das ist nicht richtig. Folgendes passiert: Da die Eingabeumleitung <nach der Pipe ( |) ausgeführt wird, wird sie überschrieben . Ist echo "bla"also nicht zur Stange geleitet. Stattdessen wird die Ausgabe von fooals Standardeingabe an umgeleitet bar. Um dies zu beheben, lesen Sie den folgenden Befehl und die Ausgabe:

$ echo "bla" | cat < <(echo "foo")
foo

Wie Sie sehen, echo "bla"wird durch abgelöst echo "foo".

Sehen Sie sich nun diesen Befehl an:

$ echo "bar" | cat < <(awk '{printf "%s and foo", $0}')
bar and foo

Also echo "bar"wird an weitergeleitet awk, was stdin liest und den String and foozur Ausgabe hinzufügt . Dieser Ausgang wird weitergeleitet cat.


Und meine Frage ist: "Ist die Tatsache, dass awk" bar "lautet, ein definiertes Verhalten?"
Etam1024

Ja ist es. cmd1 < <(cmd2)verhält sich genauso wie cmd2 | cmd1.
Chaos

Oder cmd1 | cmd2 | cmd3ist das gleiche wiecmd1 | cmd3 < <(cmd2)
Chaos

3
Wenn es Wikipedia wäre, würde ich Ihre Aussagen mit einem "Zitat benötigt" -Tag versehen :) Der springende Punkt meiner Frage ist, dass es so funktioniert, wie Sie es sagen, aber ich konnte keine Dokumentation dazu finden.
Etam1024
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.