GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Was genau ist <() in bash (und =() in zsh)?

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.


Linux
  1. Unterschied zwischen ' und ' in der Befehlszeile (bash)??

  2. Was genau passiert, wenn ich eine Datei in der Shell ausführe?

  3. Welche Funktionen sind in Zsh und fehlen in Bash oder umgekehrt?

  4. Was ist SUID, SGID und Sticky Bit?

  5. Wie kann ich die Größe jeder Datei und jedes Verzeichnisses auflisten und in Bash nach absteigender Größe sortieren?

Linux-Dateibefehl:Was macht er und wie wird er verwendet?

Ls-Befehl in Linux (Dateien und Verzeichnisse auflisten)

Was ist Zsch? Sollten Sie es verwenden?

Was ist eine .sh-Datei?

Was ist `S_ISREG()` und was macht es?

Was ist eine .so-Datei?