Angenommen, ich habe auch Programme a
und b
kann mit ./a
und ausgeführt werden ./b
.
Ist es möglich, ihre Ausgaben zu unterscheiden, ohne vorher in temporäre Dateien zu schreiben?
Angenommen, ich habe auch Programme a
und b
kann mit ./a
und ausgeführt werden ./b
.
Ist es möglich, ihre Ausgaben zu unterscheiden, ohne vorher in temporäre Dateien zu schreiben?
Antworten:
Verwenden Sie <(command)
diese Option, um die Ausgabe eines Befehls an ein anderes Programm zu übergeben, als wäre es ein Dateiname. Bash leitet die Ausgabe des Programms an eine Pipe weiter und übergibt einen Dateinamen wie /dev/fd/63
an den äußeren Befehl.
diff <(./a) <(./b)
Ebenso können Sie verwenden, >(command)
wenn Sie etwas in einen Befehl einfügen möchten .
Dies wird in Bashs Manpage als "Process Substitution" bezeichnet.
-bash: syntax error near unexpected token ('
. Ich versuchte es erneut ohne Klammern und bekam -bash: java: No such file or directory
. Funktioniert es nicht, wenn der Befehl Parameter hat?
alias diffcmd bash -c \'diff \<\(sh -c \!:1\) \<\( sh -c \!:2 \)\'
. (Dann zum Beispiel: diffcmd "ls" "ls -a").
fseek
einspeisen müssen, das aufruft , bietet zsh Angebote an =(./a)
, die identisch <(./a)
verwendet werden können, aber eine temporäre Datei unter der Haube verwenden, die zsh für Sie löscht.)
Wenn Sie zu beiden Antworten hinzufügen möchten, verwenden Sie vimdiff
:
vimdiff <(./a) <(./b)
Etwas wie das:
vimdiff
erstellt schöne, intelligente und interaktive Differenzvergleichsansichten. Es scheint auf den vim
meisten Systemen mit dem Paket zu kommen.
vimdiff
zeigt auch nicht nur die unterschiedliche Zeile, sondern auch das spezifische Textfragment, das sich unterscheidet.
Eine Möglichkeit wäre die Verwendung von Named Pipes (FIFOs) :
mkfifo a_fifo b_fifo
./a > a_fifo &
./b > b_fifo &
diff a_fifo b_fifo
... aber John Kugelmans Lösung ist viel sauberer.
rm a_fifo b_fifo
.
Für alle Neugierigen ist dies die Art und Weise, wie Sie bei der Verwendung der Fischschale eine Prozessersetzung durchführen :
Bash:
diff <(./a) <(./b)
Fisch:
diff (./a | psub) (./b | psub)
Leider ist die Umsetzung bei Fischen derzeit mangelhaft ; Fische hängen entweder oder verwenden eine temporäre Datei auf der Festplatte. Sie können psub auch nicht für die Ausgabe Ihres Befehls verwenden.
Ein bisschen mehr zu den bereits guten Antworten hinzufügen (hat mir geholfen!):
Der Befehl docker
gibt seine Hilfe an STD_ERR
(dh Dateideskriptor 2) aus.
Ich wollte sehen, ob docker attach
und docker attach --help
gab die gleiche Ausgabe
$ docker attach
$ docker attach --help
Nachdem ich gerade diese beiden Befehle eingegeben hatte, tat ich Folgendes:
$ diff <(!-2 2>&1) <(!! 2>&1)
!! ist dasselbe wie! -1, was bedeutet, dass der Befehl 1 vor diesem ausgeführt wird - dem letzten Befehl
! -2 bedeutet, dass Sie den Befehl zwei vor diesem ausführen
2> & 1 bedeutet, dass die Ausgabe von file_descriptor 2 (STD_ERR) an dieselbe Stelle gesendet wird wie die Ausgabe von file_descriptor 1 (STD_OUT).
Hoffe, dass dies von Nutzen war.
Bei zsh wird mit using =(command)
automatisch eine temporäre Datei erstellt und =(command)
durch den Pfad der Datei selbst ersetzt. Bei normaler Prozessersetzung $(command)
wird durch die Ausgabe des Befehls ersetzt.
Diese zsh-Funktion ist sehr nützlich und kann wie folgt verwendet werden, um die Ausgabe von zwei Befehlen mit einem Diff-Tool zu vergleichen, z. B. Beyond Compare:
bcomp =(ulimit -Sa | sort) =(ulimit -Ha | sort)
Beachten Sie für Beyond Compare, dass Sie bcomp
für das oben Gesagte (anstelle von bcompare
) verwenden müssen, da bcomp
der Vergleich gestartet und auf den Abschluss gewartet wird . Wenn Sie verwenden bcompare
, 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:
Beachten Sie, dass die Shell eine temporäre Datei erstellt und diese löscht, wenn der Befehl beendet ist.
und das Folgende ist der Unterschied zwischen $(...)
und =(...)
:
Wenn Sie die Manpage von zsh lesen, stellen Sie möglicherweise fest, dass <(...) eine andere Form der Prozessersetzung ist, die = (...) ähnelt. Es gibt einen wichtigen Unterschied zwischen den beiden. Im Fall <(...) erstellt die Shell anstelle einer Datei eine Named Pipe (FIFO). Dies ist besser, da es das Dateisystem nicht ausfüllt. aber es funktioniert nicht in allen Fällen. Wenn wir in den obigen Beispielen = (...) durch <(...) ersetzt hätten, hätten alle außer fgrep -f <(...) aufgehört zu arbeiten. Sie können eine Pipe nicht bearbeiten oder 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 es feststellt, dass eines seiner Argumente - ist, und dann seine Standardeingabe in die temporäre Datei kopiert.