Ich hatte mir vorgestellt, dass der einfachste Weg, den Inhalt zweier ähnlicher Verzeichnisse zu vergleichen, so etwas wie wäre
diff `ls old` `ls new`
Aber ich verstehe, warum das nicht funktioniert. diff
Statt zwei Streams, wie ich es mir erhofft hatte, wird eine große, lange Liste von Dateien auf der Kommandozeile ausgegeben. Wie übergebe ich die beiden Ausgänge direkt an diff?
command-line
diff
Ternary
quelle
quelle
Antworten:
Substitution Befehl
`…`
ersetzt die Ausgabe des Befehls in die Kommandozeile, so dassdiff
die Liste der Dateien in beiden Verzeichnissen als Argument sieht. Sie möchten, dassdiff
in der Befehlszeile zwei Dateinamen angezeigt werden und der Inhalt dieser Dateien die Verzeichnislisten sind. Das ist, was die Prozesssubstitution tut.Die Argumente, die
diff
aussehen wird/dev/fd/3
und/dev/fd/4
: sie sind entsprechende Datei - Deskriptoren zu zwei von bash erstellt Rohren. Wenndiff
diese Dateien geöffnet werden, wird sie mit der Leseseite jeder Pipe verbunden. Die Schreibseite jeder Pipe ist mit demls
Befehl verbunden.quelle
echo <(echo) <(echo)
hätte nie gedacht, dass dies so interessant sein könnte: Dls
ist, dass es Dateinamen entstellt . Das Parsen der Ausgabe ist fragil (es funktioniert nicht mit „seltsamen“ Dateinamen). Für den Vergleich zweier Verzeichnislisten ist es in Ordnung, solange die Ausgabe eindeutig ist. Bei beliebigen Dateinamen würde dies eine Option erfordern, wie z--quoting-style=escape
.<(…)
erzeugt eine Pipe. Es scheint, dass die Verbindung mit Rohren nicht funktioniert, Sie können sie also nicht verwenden<(…)
. In zsh können Sie ersetzen<(…)
durch=(…)
und es wird funktionieren, weil=(…)
die Zwischenausgaben in einer temporären Datei abgelegt werden. In Bash glaube ich nicht, dass es eine bequeme Syntax gibt, Sie müssten die temporären Dateien selbst verwalten.Bei Verwendung von zsh wird
=(command)
automatisch eine temporäre Datei erstellt und=(command)
durch den Pfad der Datei selbst ersetzt. Bei der Befehlsersetzung$(command)
wird diese durch die Ausgabe des Befehls ersetzt.Es gibt also drei Möglichkeiten:
$(...)
<(...)
=(...)
zsh Flavoured Process Subsitution, # 3, ist sehr nützlich und kann verwendet werden, um die Ausgabe von zwei Befehlen mit einem Diff-Tool zu vergleichen, zum Beispiel Beyond Compare:
Beachten Sie, dass Sie für Beyond Compare
bcomp
(anstelle vonbcompare
) verwenden müssen, dabcomp
der Vergleich gestartet und abgewartet wird , bis er abgeschlossen ist. Wenn Sie verwendenbcompare
, wird der Vergleich gestartet und sofort beendet, wodurch die temporären Dateien, die zum Speichern der Ausgabe der Befehle erstellt wurden, verschwinden.Lesen Sie hier mehr: http://zsh.sourceforge.net/Intro/intro_7.html
Beachten Sie auch Folgendes:
und das Folgende ist der Unterschied zwischen den beiden Arten der von zsh unterstützten Prozessersetzung (dh # 2 und # 3):
Referenz: https://unix.stackexchange.com/questions/393349/differenz zwischen- subshells-and- process-substitution
quelle
$(...)
ist keine Prozessersetzung, sondern eine Befehlssetzung .<(...)
ist Prozesssubstitution. Deshalb wird in der zitierten Passage überhaupt nicht erwähnt$(...)
.Fischmuschel
In Fish Shell musst du in psub pipen . Hier ist ein Beispiel eines Heroku- und Dokku-Konfigurationsvergleichs mit Beyond Compare :
quelle
meld
Open Source und in den Repositories von Ubuntu und EPEL verfügbar. meldmerge.orgIch verwende oft die in der akzeptierten Antwort beschriebene Technik:
Aber ich finde, ich benutze es normalerweise mit viel komplexeren Befehlen als im obigen Beispiel. In solchen Fällen kann es ärgerlich sein, den Befehl diff zu erstellen. Ich habe einige Lösungen gefunden, die für andere nützlich sein könnten.
In 99% der Fälle probiere ich die entsprechenden Befehle aus, bevor ich diff ausführe. Folglich sind die Befehle, die ich unterscheiden möchte, genau dort in meinem Verlauf ... warum nicht sie verwenden?
Ich benutze den eingebauten Fix Command (fc) -Bash, um die letzten beiden Befehle auszuführen:
Die fc Flags sind:
Sie
-1
-1
beziehen sich auf die Start- und Endposition in der Historie, in diesem Fall vom letzten Befehl bis zum letzten Befehl, der nur den letzten Befehl liefert.Zuletzt schließen wir dies ein
$()
, um den Befehl in einer Subshell auszuführen.Offensichtlich ist es etwas mühsam, dies einzugeben, damit wir einen Alias erstellen können:
Oder wir können eine Funktion erstellen:
Dies unterstützt die Angabe der zu verwendenden Verlaufszeilen. Nach der Verwendung von beiden finde ich, dass der Alias die Version ist, die ich bevorzuge.
quelle