Dies wird Prozesssubstitution genannt.
Der <(list)
Syntax wird von beiden unterstützt, bash
und zsh
. Es bietet eine Möglichkeit, die Ausgabe eines Befehls (list
) zu einem anderen Befehl, wenn eine Pipe verwendet wird (|
) Ist nicht möglich. Zum Beispiel, wenn ein Befehl die Eingabe von STDIN
einfach nicht unterstützt oder Sie benötigen die Ausgabe mehrerer Befehle:
diff <(ls dirA) <(ls dirB)
<(list)
verbindet den Ausgang von list
mit einer Datei in /dev/fd
, falls vom System unterstützt, ansonsten wird eine Named Pipe (FIFO) verwendet (was auch von der Unterstützung durch das System abhängt; keine Anleitung sagt, was passiert, wenn beide Mechanismen nicht unterstützt werden, vermutlich bricht es mit einem Fehler ab). Der Name der Datei wird dann als Argument auf der Kommandozeile übergeben.
zsh
unterstützt zusätzlich =(list)
als möglicher Ersatz für <(list)
. Mit =(list)
statt der Datei in /dev/fd
wird eine temporäre Datei verwendet oder ein FIFO. Es kann als Ersatz für <(list)
verwendet werden wenn das Programm in der Ausgabe suchen muss.
Laut ZSH-Handbuch können auch andere Probleme mit <(list)
auftreten funktioniert:
Die =
Form ist sowohl als /dev/fd
nützlich und die benannte Pipe-Implementierung von <(...)
Nachteile haben. Im ersteren Fall schließen einige Programme möglicherweise den betreffenden Dateideskriptor automatisch, bevor sie die Datei auf der Befehlszeile untersuchen, insbesondere wenn dies aus Sicherheitsgründen erforderlich ist, z. B. wenn das Programm setuid ausführt. Im zweiten Fall, wenn das Programm die Datei nicht tatsächlich öffnet, wird die Subshell, die versucht, aus der Pipe zu lesen oder in die Pipe zu schreiben, für immer blockieren (in einer typischen Implementierung können verschiedene Betriebssysteme unterschiedliches Verhalten haben) und muss explizit beendet werden . In beiden Fällen liefert die Shell die Informationen tatsächlich über eine Pipe, sodass Programme, die eine Suche erwarten (siehe Manpage lseek(2)
) in der Datei funktioniert nicht.
Beachten Sie, dass dies eine Bash-Antwort ist, nicht zsh.
In Bash gibt es Fälle, in denen Sie keine Pipes verwenden können:
some_command | some_other_command
Da Pipes Subshells für jede Komponente der Pipeline einführen, verschwinden alle Nebeneffekte, auf die Sie sich verlassen haben, wenn die Subshells beendet werden. Zum Beispiel dieses erfundene Beispiel:
cat file | while read line; do ((count++)); done
echo $count
wird eine Leerzeile angezeigt, da der $count
Variable existiert in der aktuellen Shell nicht.
Eine Bash-Prozessersetzung ermöglicht es Ihnen, dieses Rätsel zu vermeiden, indem Sie aus der Ausgabe von "some_command" lesen können, wie Sie es aus einer Datei tun würden
while read line; do ((count++)); done < <(cat file)
# ....................................1.2
echo $count # the variable *does* exist in the current shell
(1) ist eine normale Eingabeumleitung. (2) ist der Anfang von <()
Ersetzungssyntax verarbeiten.