Frage Wie verteile ich die Ausgabe von zwei Befehlen?


Ich hatte mir vorgestellt, dass der einfachste Weg, den Inhalt von zwei ähnlichen Verzeichnissen zu vergleichen, etwas wie sein würde

diff `ls old` `ls new`

Aber ich verstehe, warum das nicht funktioniert. diff wird eine große lange Liste von Dateien in der Befehlszeile übergeben, anstatt zwei Streams, wie ich es mir erhofft hatte. Wie übergebe ich die beiden Ausgänge direkt an diff?


133
2017-12-15 22:01


Ursprung


Verbunden: Wie kann ich die Ausgabe von zwei Unix-Befehlen vergleichen, um den Unterschied zu finden?, Diff-Ausgabe von zwei Programmen ohne temporäre Dateien - kenorb


Antworten:


Befehlsersetzung `…` ersetzt die Ausgabe des Befehls in der Befehlszeile, also diff sieht die Liste der Dateien in beiden Verzeichnissen als Argumente. Was Sie wollen, ist für diff um zwei Dateinamen in der Befehlszeile anzuzeigen, und den Inhalt dieser Dateien als Verzeichnislisten haben. Das ist, was Prozesssubstitution tut.

diff <(ls old) <(ls new)

Die Argumente zu diff wird aussehen wie /dev/fd/3 und /dev/fd/4Sie sind Dateideskriptoren, die zwei von bash erstellten Pipes entsprechen. Wann diff öffnet diese Dateien, es wird mit der Leseseite jeder Pipe verbunden. Die Schreibseite jedes Rohrs ist mit dem verbunden ls Befehl.


194
2017-12-15 22:06



echo <(echo) <(echo) hätte nie gedacht, dass das so interessant sein könnte: D - Aquarius Power
Prozesssubstitution ist nicht von allen Shells unterstützt, aber Rohrweiterleitungen sind a nette Abhilfe. - Irfan434
Nur um zu erwähnen, dass das Parsen von ls nicht empfohlen wird unix.stackexchange.com/questions/128985/why-not-parse-ls - Katu
@Katu Das Problem mit ls ist, dass es Dateinamen mischt. Das Analysieren seiner Ausgabe ist zerbrechlich (es funktioniert nicht mit "seltsamen" Dateinamen). Zum Vergleichen zweier Verzeichnislisten ist es in Ordnung, solange die Ausgabe eindeutig ist. Bei beliebigen Dateinamen würde dies eine Option wie z --quoting-style=escape. - Gilles


Fischschale

In Fish Shell musst du reinstecken Psub. Hier ist ein Beispiel für Heroku und Dokku Config Vergleich mit Unvergleichlich:

bcompare (ssh me@myapp.pl dokku config myapp | sort | psub) (heroku config -a myapp | sort | psub)

2
2018-04-12 07:34



Ein anderes grafisches Diff-Tool ist meld Das ist Open Source und verfügbar in den Ubuntu und EPEL Repositories. meldmerge.de - phiphi


Für zsh, mit =(command) erstellt automatisch eine temporäre Datei und ersetzt sie =(command) mit dem Pfad der Datei selbst. Mit Befehlsersetzung, $(command) wird durch die ersetzt Ausgabe des Befehls.

Also gibt es drei Möglichkeiten:

  1. Befehlsersetzung: $(...) 
  2. Prozesssubstitution: <(...)
  3. zsh-aromatisierte Prozessersetzung: =(...)

Die zsh-artige Prozesssubstitution, # 3, ist sehr nützlich und kann so verwendet werden, um die Ausgabe von zwei Befehlen mit einem Diff-Tool zu vergleichen, zum Beispiel Beyond Compare:

bcomp  =(ulimit -Sa | sort) =(ulimit -Ha | sort)

Beachten Sie, dass Sie für Beyond Compare verwenden müssen bcomp für das obige (statt bcompare) schon seit bcomp startet den Vergleich und wartet um es zu vervollständigen. Wenn du benutzt bcompare, der einen Vergleich startet und sofort beendet wird, aufgrund dessen die temporären Dateien verschwinden, die zum Speichern der Ausgabe der Befehle erstellt wurden.

Lesen Sie hier mehr: http://zsh.sourceforge.net/Intro/intro_7.html

Bemerke das auch:

Beachten Sie, dass die Shell eine temporäre Datei erstellt und sie löscht, wenn der Befehl beendet ist.

und das folgende, was der Unterschied zwischen den zwei Typen von Prozesssubstitution ist, die von zsh unterstützt werden (d. h. # 2 und # 3):

Wenn Sie zhs man-Seite lesen, stellen Sie vielleicht fest, dass <(...) eine andere Form der Prozesssubstitution ist, die ähnlich ist wie = (...). Es gibt einen wichtigen Unterschied zwischen den beiden. Im Fall <(...) erstellt die Shell eine benannte Pipe (FIFO) anstelle einer Datei. Dies ist besser, da es das Dateisystem nicht füllt; aber es funktioniert nicht in allen Fällen. Wenn wir in den obigen Beispielen = (...) durch <(...) ersetzt hätten, hätten alle mit Ausnahme von fgrep -f <(...) aufgehört zu arbeiten. Sie können eine Pipe nicht bearbeiten oder sie als E-Mail-Ordner öffnen. fgrep hat jedoch kein Problem damit, eine Liste von Wörtern aus einer Pipe zu lesen. Sie fragen sich vielleicht, warum diff <(foo) bar nicht funktioniert, da foo | diff - bar funktioniert; Dies liegt daran, dass diff eine temporäre Datei erstellt, wenn sie feststellt, dass eines ihrer Argumente - ist, und dann ihre Standardeingabe in die temporäre Datei kopiert.

Referenz: https://unix.stackexchange.com/questions/393349/difference-between-subshells-and-process-substitution


2
2018-06-29 08:59



$(...) ist nicht Prozesssubstitution, es ist Befehl Auswechslung. <(...) ist Prozesssubstitution. Deshalb erwähnt die zitierte Passage nicht $(...) überhaupt. - muru