Gibt es einen Unterschied zwischen command1 | command2
und command2 <(command1)
?
Zum Beispiel git diff | more
vs more <(git diff)
Mein Verständnis ist, dass beide das stdout von command2
nehmen und es an die stdin von command1
übergeben.
Der Hauptunterschied besteht darin, dass <(
... )
, "Prozesssubstitution" genannt, von der Shell in einen Dateinamen übersetzt wird, der als reguläres Argument an den Befehl übergeben wird. Es sendet nichts an die Standardeingabe des Befehls. Dies bedeutet, dass es nicht direkt mit Befehlen wie tr
verwendet werden kann, die kein Dateinamenargument verwenden:
Sie können jedoch immer ein weiteres <
vor das <(
... )
setzen, um es stattdessen in eine Eingabeumleitung umzuwandeln:
Und da es einen Dateinamen generiert, können Sie die Prozesssubstitution mit Befehlen verwenden, die mehr als ein Dateiargument enthalten:
%Vor%Der andere wichtige Unterschied besteht darin, dass eine Pipe Subshells erstellt, die in der übergeordneten Umgebung keine Nebenwirkungen haben können:
%Vor%Aber bei Prozesssubstitution befindet sich nur der Prozess innerhalb der Klammern in einer Untershell; Der Umgebungsbefehl kann immer noch Nebenwirkungen haben:
%Vor% Erwähnenswert ist, dass Sie auch in einen Prozess mit >(
... )
schreiben können, obwohl es weniger Fälle gibt, in denen das nützlich ist:
a | b
nimmt die stdout
Ausgabe von der ausführbaren Datei a
und füttert sie in die ausführbare Datei b
als b's stdin
.
a > b
übernimmt die stdout
von der ausführbaren Datei a
und leitet sie weiter / schreibt sie in die Datei b
.
a < b
übernimmt den Inhalt der Datei b
und leitet ihn in die ausführbare Datei a
als stdin
Mit anderen Worten, |
pipes gibt zwischen Programmen aus, während <
und >
Dateien in / aus Programmen pipesiert.
Ihre Version mit ()
führt einen zusätzlichen Prozess aus, während Sie im Wesentlichen dasselbe tun.