Zwei Pipes zu einem Befehl

9

Die folgende Syntax verwirrt mich ein wenig. Obwohl es funktioniert, versteht es nicht, warum es funktioniert. Es scheint, als wären dem Befehl diff zwei Pipes zugeordnet. Aber gibt es nicht nur einen STDIN?

Beispiele:

diff <(echo "foobar") <(echo "barbaz")
diff <(cat foo.txt) <(cat bar.txt)
iblue
quelle
Hier ist ein Link zum relevanten Thema - Prozessersetzung - in der bashManpage.
Chepper

Antworten:

13

Die Pipes sind einfach an andere Dateideskriptoren als 0 (stdin) gebunden:

$ echo <(true)
/dev/fd/63
$ echo <(true) <(true)
/dev/fd/63 /dev/fd/62

Ein Prozess kann natürlich mehr als einen offenen Dateideskriptor gleichzeitig haben, daher gibt es kein Problem.

Sven Marnach
quelle
Wenn ich nur die so genannten temporären Pipes gekannt hätte, hätte ich sie googeln können. Danke!
@iblue: Ich glaube nicht, dass es "temporäre Pipes" heißt. Es sind nur Pipes, wie sie vom pipe()Systemaufruf erstellt wurden.
Sven Marnach
Um genau zu sein, könnte es "anonyme Named Pipes" genannt werden, aber es reicht aus, es zu googeln.
2
@WilliamPursell: Es sind keine Dateien beteiligt. Die Shell erstellt eine anonyme Pipe mit pipe()und teilt die Unterprozesse auf. Der Hauptprozess hat zusätzliche Dateideskriptoren geöffnet hat , wenn ein anonymes Rohr verwendet wird. Diese zusätzlichen Dateideskriptoren werden im Formular übergeben /dev/fd/..., und der Prozess öffnet sie normalerweise einfach unter Verwendung dieser Dateinamen. Dies führt dazu, dass sie dup()bearbeitet werden und noch offenere Dateideskriptoren erstellt werden. Der Prozess könnte auch den benannten Dateideskriptor sofort ohne offene Aufrufe verwenden ...
Sven Marnach
1
... wie in diesem kleinen und dummen Testprogramm gezeigt . Nach dem Kompilieren mit habe aich es als aufgerufen ./a <(ls)und die Liste der Dateien erfolgreich gedruckt, um zu beweisen, dass der benannte Dateidekriptor (in meinem Fall 63) bereits geöffnet war. Die Bash verwendet möglicherweise Named Pipes in einem temporären Verzeichnis auf anderen Architekturen als Linux. In diesem Fall sind beim Aufrufen des Hauptprozesses keine zusätzlichen Dateideskriptoren geöffnet.
Sven Marnach