Prozesssubstitution mit Eingabeumleitung

7

Ich versuche, die Umleitung von Eingaben in Kombination mit der Substitution von Prozessen zu verstehen. Ich benutze bash3

Ein Beispiel mit trist das folgende

$ tr "o" "a" <(echo "Foo")
tr: extra operand `/dev/fd/63'
Try `tr --help' for more information.

Ich glaube ich verstehe warum das nicht funktioniert. Die Prozessersetzung <( )erstellt einen Dateideskriptor, in dem trnur von der Standardeingabe gelesen wird.

Wie kann ich dafür sorgen, dass es mit der richtigen Umleitung funktioniert?

Ich weiß, dass ich einfach Rohre verwenden könnte:

$ echo "Foo" | tr "o" "a"
Faa

Ich versuche jedoch, ein besseres Verständnis zu bekommen. Ich habe etwas mit Hilfe von man bashversucht <&, aber ich weiß nicht wirklich, was ich tue.

Wie kann ich die Prozessersetzung richtig verwenden tr?

Bernhard
quelle

Antworten:

10

Sie waren wirklich nah:

tr "o" "a" < <(echo "Foo")

Die Ersetzung erstellt <()einen Dateideskriptor und fügt nur den Pfad zur Shell ein. Zum Verständnis einfach ausführen:

<(echo blubb)

Sie werden den Fehler sehen:

-bash: /dev/fd/63: Permission denied

Deshalb wird es einfach /dev/fd/63in die Schale /dev/fd/63eingefügt und ist nicht auslösbar, da es sich um eine einfache Pfeife handelt. Im trobigen Beispiel echo "Foo"schreibt es in die Pipe und über die Eingabeverleitung <wird der trBefehl aus dem Dateideskriptor gelesen.

Chaos
quelle
Aah, natürlich habe ich versucht <<(: o. Vielen Dank!
Bernhard
4
ls -ld <(echo blubb)kann eine bessere Illustration sein.
Stéphane Chazelas
3

Ich fand die Bash One-Liners Explained- Serie sehr nützlich, um mehr über all diese Dinge zu verstehen.

In dem oben verlinkten Artikel geht es speziell um die Umleitung von Eingaben.

So lösen Sie das obige Beispiel:

> tr "o" "a" <<< $(echo "Foo")
Faa
jas_raj
quelle
Dies verwendet eine "Here-Zeichenfolge", führt jedoch keine Eingabeumleitung durch. Obwohl es bei meiner Frage möglich ist, bricht es bei mehrzeiliger Eingabe (soweit ich aus meinen Tests
Bernhard
2
@ Bernard. Es wird umgeleitet. Zuerst wird es echo Fooin einer Unterschale ausgeführt, deren Ausgabe auf eine Pipe umgeleitet wird. Es liest diese Ausgabe vom anderen Ende der Pipe und speichert sie (abzüglich der nachfolgenden Zeilenumbrüche). Sobald eof auf dieser Pipe erreicht ist, führt es abhängig von der Shell eine Wortaufteilung durch und verbindet die resultierenden Wörter mit Leerzeichen ( bash) oder nicht (zsh, ksh93). Und speichert das und einen Zeilenumbruch in einer temporären Datei. Dann wird die trEingabe von dieser temporären Datei umgeleitet.
Stéphane Chazelas
@ StéphaneChazelas (wurde durch Ihre Bemerkung nicht benachrichtigt). Ich wusste nicht, dass der Here-String auch temporäre Dateien verwendet, aber das macht Sinn. Vielen Dank.
Bernhard