Ich habe nie wirklich darüber nachgedacht, wie die Shell tatsächlich Pipe-Befehle ausführt. Ich habe immer gesagt, dass die „stdout eines Programms wird verrohrt in den stdin eines anderen,“ als eine Möglichkeit , über Rohre zu denken. Also dachte ich natürlich, dass im Falle von sagen wir, A | B, A würde zuerst ausgeführt, dann erhält B die Standardausgabe von A und verwendet die Standardausgabe von A als Eingabe.
Ich habe jedoch festgestellt, dass bei der Suche nach einem bestimmten Prozess in ps grep -v "grep" am Ende des Befehls eingefügt wird, um sicherzustellen, dass grep nicht in der endgültigen Ausgabe angezeigt wird. Dies bedeutet, dass im Befehl ps aux | grep "bash" | grep -v "grep", was bedeutet, dass ps wusste, dass grep ausgeführt wird und daher in der Ausgabe von ps enthalten ist. Aber wenn ps die Ausführung beendet, bevor die Ausgabe an grep weitergeleitet wird, woher wusste es dann, dass grep ausgeführt wird?
flamingtoast@FTOAST-UBUNTU: ~$ ps | grep ".*"
PID TTY TIME CMD
3773 pts/0 00:00:00 bash
3784 pts/0 00:00:00 ps
3785 pts/0 00:00:00 grep
Antworten:
Weitergeleitete Befehle werden gleichzeitig ausgeführt. Wenn Sie rennen
ps | grep …
, ist es das Glück der Auslosung (oder eine Frage der Funktionsweise der Shell in Kombination mit der Feinabstimmung des Schedulers tief im Inneren des Kernels), ob Sie zuerst beginnenps
odergrep
beginnen, und auf jeden Fall fahren Sie fort gleichzeitig ausführen.Dies wird sehr häufig verwendet, um dem zweiten Programm die Verarbeitung von Daten zu ermöglichen, die aus dem ersten Programm stammen, bevor das erste Programm seine Operation abgeschlossen hat. Zum Beispiel
Beginnt, die übereinstimmenden Zeilen in Großbuchstaben anzuzeigen, noch bevor
grep
das Durchlaufen der großen Datei abgeschlossen ist.zeigt die erste übereinstimmende Zeile an und beendet möglicherweise die Verarbeitung, bevor
grep
das Lesen der Eingabedatei abgeschlossen ist.Wenn Sie irgendwo gelesen haben, dass Pipe-Programme nacheinander ausgeführt werden, fliehen Sie aus diesem Dokument. Weitergeleitete Programme werden gleichzeitig ausgeführt und haben dies immer getan.
quelle
grep
Programm und einen Puffer, der vom Kernel in der Pipe selbst verwaltet wird. Letzteres finden Sie unter Wie groß ist der Pipe-Puffer?Die Reihenfolge, in der die Befehle ausgeführt werden, spielt eigentlich keine Rolle und kann nicht garantiert werden. Abgesehen von den arcane Einzelheiten
pipe()
,fork()
,dup()
undexecve()
schafft die Schale zuerst das Rohr, die Leitung für die Daten , die zwischen den Prozessen fließen wird, und erzeugt dann die Prozesse mit den Enden des Rohres mit ihnen verbunden sind . Der erste Prozess, der ausgeführt wird, blockiert möglicherweise das Warten auf Eingaben vom zweiten Prozess oder das Warten auf den zweiten Prozess, um das Lesen von Daten von der Pipe zu starten. Diese Wartezeiten können beliebig lang sein und spielen keine Rolle. Unabhängig von der Reihenfolge, in der die Prozesse ausgeführt werden, werden die Daten schließlich übertragen und alles funktioniert.quelle
Das Risiko, ein totes Pferd zu schlagen, scheint das Missverständnis zu sein
ist äquivalent zu
Aber als Unix erstellt wurde und Kinder mit Dinosauriern zur Schule fuhren, waren die Festplatten sehr klein, und es war üblich, dass ein ziemlich harmloser Befehl den gesamten freien Speicherplatz in einem Dateisystem verbrauchte. Wenn
B
so etwas wäre , könnte die endgültige Ausgabe der Pipeline viel kleiner sein als diese Zwischendatei. Aus diesem Grund wurde die Pipe nicht als Abkürzung für das Modell "Führen Sie zuerst A und dann B mit Eingaben aus dem Ausgabemodell von A aus " entwickelt, sondern als Möglichkeit , sie gleichzeitig mit der Zwischendatei auszuführen und das Speichern der Zwischendatei zu vermeiden auf der Festplatte.grep some_very_obscure_string
B
A
quelle
Normalerweise führen Sie dies unter Bash aus. Der Prozess läuft und startet gleichzeitig, wird aber von der Shell parallel ausgeführt. Wie ist es möglich?
Das System garantiert nicht, wie schnell Exec ausgeführt wird und der angegebene Befehl startet. Es ist unabhängig von der Shell, aber dem System. Das ist weil:
einmal zeigen
grep
und / oderps
befehl, und als nächstes jetzt. Es hängt davon ab, wie schnell der Kernel Prozesse mithilfe der System-Exec-Funktion startet.quelle
exec()
ausgeführt, sondern wie dieexec()
Aufrufe und die Ausführung der Programme in einer Pipe verschachtelt sind .