Eine einzeilige Datei mit 2 tmp-Dateien (nicht das, was Sie wollen) wäre:
foo | bar > file1.txt && baz | quux > file2.txt && diff file1.txt file2.txt
Mit bash könnten Sie jedoch versuchen:
diff <(foo | bar) <(baz | quux)
foo | bar | diff - <(baz | quux) # or only use process substitution once
Die 2. Version wird Sie deutlicher daran erinnern, welche Eingabe welche war, indem Sie
-- /dev/stdin
vs. ++ /dev/fd/63
oder etwas anstelle von zwei nummerierten fds anzeigen.
Nicht einmal eine Named Pipe wird im Dateisystem angezeigt, zumindest unter Betriebssystemen, in denen bash die Prozessersetzung mithilfe von Dateinamen implementieren kann /dev/fd/63
, um einen Dateinamen zu erhalten, den der Befehl öffnen und lesen kann, um tatsächlich aus einem bereits geöffneten Dateideskriptor zu lesen, den bash festgelegt hat vor dem Ausführen des Befehls. (dh bash verwendet pipe(2)
vor fork und dup2
leitet dann von der Ausgabe von quux
zu einem Eingabedateideskriptor für umdiff
auf fd 63 um.)
Auf einem System ohne "magisch" /dev/fd
oder/proc/self/fd
bash bash möglicherweise Named Pipes, um die Prozessersetzung zu implementieren, verwaltet sie jedoch im Gegensatz zu temporären Dateien zumindest selbst, und Ihre Daten werden nicht in das Dateisystem geschrieben.
Sie können überprüfen, wie bash die Prozessersetzung implementiert echo <(true)
, um den Dateinamen zu drucken, anstatt daraus zu lesen. Es wird /dev/fd/63
auf einem typischen Linux-System gedruckt . Oder um weitere Informationen darüber zu erhalten, welche Systemaufrufe bash verwendet, verfolgt dieser Befehl auf einem Linux-System Datei- und Dateideskriptorsystemaufrufe
strace -f -efile,desc,clone,execve bash -c '/bin/true | diff -u - <(/bin/true)'
Ohne Bash könnten Sie eine Named Pipe erstellen . Verwenden Sie -
diese diff
Option, um eine Eingabe von STDIN zu lesen und die Named Pipe als die andere zu verwenden:
mkfifo file1_pipe.txt
foo|bar > file1_pipe.txt && baz | quux | diff file1_pipe.txt - && rm file1_pipe.txt
Beachten Sie, dass Sie mit dem Befehl tee nur einen Ausgang an mehrere Eingänge weiterleiten können:
ls *.txt | tee /dev/tty txtlist.txt
Der obige Befehl zeigt die Ausgabe von ls * .txt an das Terminal an und gibt sie an die Textdatei txtlist.txt aus.
Mit der Prozessersetzung können Sie jedoch tee
dieselben Daten in mehrere Pipelines einspeisen:
cat *.txt | tee >(foo | bar > result1.txt) >(baz | quux > result2.txt) | foobar
mkfifo a; cmd >a& cmd2|diff a -; rm a