Von diesem Kommandozeilenbeitrag :
$ diff <(wget -q -O - URL1) <(wget -q -O - URL2)
Scheint wie mehrere Standardeingaben, aber --- wenn ich mich richtig an meinen Linux-Programmierkurs erinnere --- kann das nicht sein. Ich dachte, dass die Standardeingabe per Definition ein Stream ist.
Vielleicht hat das ja was mit stdin zu tun? Kann mir jemand das erklären; Stellen Sie möglicherweise Links zur Dokumentation bereit.
Bonus: Wie würde ein Skript mit diesen mehreren Streams umgehen? Wenn jemand ein Python- oder Perl-Beispiel bereitstellen könnte, wäre das sehr hilfreich.
<(…)
; in Zsh Prozesssubstitutionssyntax ist=(…)
.Antworten:
Dies ist keine mehrfache Standardeingabe. Dies ist ein Bash'ismus, der als "Prozessersetzung" bezeichnet wird ( http://tldp.org/LDP/abs/html/process-sub.html)
/dev/fd/something
Für jede Ersetzung wird eine Pseudodatei ( ) erstellt. Das ist ziemlich nützlich. Der Befehl kann nur als Stream gelesen werden, dh er kann nicht mit fseek hin und her gehen. Es muss als ein Strom von Bytes wie eine Pipe gelesen werden.BONUS Antwort
Sie müssen nicht zu viel tun, um dies zu nutzen. Für Ihr Skript wird in der Befehlszeile ein gültiger Dateiname angezeigt, der wie alles andere auch open () ed sein kann. Wie andere gesagt haben, würden Sie sehen
diff /dev/fd/XX /dev/fd/YY
. Wenn Sie stat () für eine dieser Pseudodateien ausführen, werden Sie feststellen, dass es sich um eine Named Pipe handelt, und Sie sollten sie mit Pipe-Semantik behandeln, dh ohne fseek () oder ftell (). Wenn Sie einen stat () -Test durchführen, um explizit zu prüfen, ob es sich um eine Datei handelt (z. B.[ -f $1 ]
), wird diese nicht mehr funktionieren - sie wird schließlich als Named Pipe implementiert.quelle
<(...)
tut Prozess Substitution in bash. Die Ausgabe des Prozesses in den Parens wird an einen zusätzlichen Dateideskriptor gesendet, der über die normale Zahl 3 hinausgeht, und ein Dateiname wird entsprechend diesem Dateideskriptor zurückgegeben. Auf diese Weise kann die Ausgabe eines Befehls als Dateiname behandelt werden, der an einen anderen Befehl übergeben wird.quelle
Es gibt eins
stdin
und einsstdout
für jeden Prozess . Sie sind normalerweise mit dem Terminal verbunden, können jedoch getrennt voneinander umgeleitet werden.Im Beispiel handelt es sich um zwei
wget
Prozesse, von denen jeder seinen eigenenstdin
und einen eigenen erhältstdout
. Jederwget
Prozess schreibt an-
, welches sein iststdout
. Dannbash
‚s Prozess Substitution<(...)
verbindet diestdout
des Prozesses zu einer einzigartigen pseudo-Datei, aus demdiff
gelesen werden kann. Beachten Sie, dass die beiden Prozessersetzungen zwei verschiedene Pseudodateien ergeben! Sodiff
sieht so etwas aus:wo das
stdout
vonwget -q -O - URL1
verbunden ist/dev/fd/XX
, und dasstdout
vonwget -q -O - URL2
zu/dev/fd/YY
.quelle