Die Frage im aktuellen Kopfgeldbescheid:
Das allgemeine Beispiel ist zu kompliziert. Kann jemand bitte erklären, wie man das folgende Beispiel implementiert?diff <(cat "$2" | xz -d) <(cat "$1" | xz -d)
scheint hier eine antwort zu haben .
Wie in Gilles 'Antwort gezeigt , besteht die allgemeine Idee darin, die Ausgabe von "Producer" -Befehlen in verschiedenen Phasen einer Pipeline an neue Gerätedateien 1 zu senden und sie "Consumer" -Befehlen zur Verfügung zu stellen, die möglicherweise Dateinamen als Argumente verwenden ( vorausgesetzt, Ihr System gibt Ihnen Zugriff auf die Dateideskriptoren als /dev/fd/X
).
Der einfachste Weg, um das zu erreichen, wonach Sie suchen, ist wahrscheinlich:
xz -cd file1.xz | { xz -cd file2.xz | diff /dev/fd/3 -; } 3<&0
(Verwenden file1.xz
statt "$1"
für die Lesbarkeit und xz -cd
statt cat ... | xz -d
weil ein einziger Befehl ausreicht).
Die Ausgabe des ersten "Producer" -Befehls xz -cd file1.xz
wird an einen zusammengesetzten Befehl ( {...}
) weitergeleitet. Anstatt jedoch sofort als Standardeingabe für den nächsten Befehl verwendet zu werden, wird sie in den Dateideskriptor dupliziert3
und somit für alle Elemente des zusammengesetzten Befehls als verfügbar gemacht /dev/fd/3
. Die Ausgabe des zweiten "Producer" -Befehls, xz -cd file2.xz
der weder seine Standardeingabe noch irgendetwas aus dem Dateideskriptor verbraucht 3
, wird dann an den "Consumer" -Befehl weitergeleitet diff
, der aus seiner Standardeingabe und aus liest /dev/fd/3
.
Piping und Duplikation von Dateideskriptoren können hinzugefügt werden, um Gerätedateien für beliebig viele "Producer" -Befehle bereitzustellen, z.
xz -cd file1.xz | { xz -cd file2.xz | { diff /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
Während es im Kontext Ihrer spezifischen Frage irrelevant sein mag, ist es erwähnenswert, dass:
cmd1 <(cmd2) <(cmd3)
, cmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
Und ( cmd2 | ( cmd3 | ( cmd1 /dev/fd/3 /dev/fd/4 ) 4<&0 ) 3<&0 )
haben verschiedene mögliche Auswirkungen auf die anfängliche Ausführungsumgebung.
Im Gegensatz zu dem, was in passiert cmd1 <(cmd2) <(cmd3)
, cmd3
und cmd1
in cmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
wird keine Eingaben des Benutzers lesen können. Dafür sind weitere Dateideskriptoren erforderlich. Zum Beispiel, um zusammenzupassen
diff <(echo foo) <(read var; echo "$var")
du wirst sowas brauchen
{ echo foo | { read var 0<&9; echo "$var" | diff /dev/fd/3 -; } 3<&0; } 9<&0
1 Weitere Informationen hierzu finden Sie in U & L, z. B. in Understanding / dev und seinen Unterverzeichnissen und Dateien .