2014-01-25 8 views
6

Warum hängt yes | head nicht?Warum hängt "ja | head" nicht?

Ich dachte, das System sammelt alle Ergebnisse von und leitet es dann zu head, und weil eine Endlosschleife ist, hängt das System. Aber es kann tatsächlich anhalten und 10 Zeilen von y anzeigen.

Wie verwaltet das System zu stoppen, wenn head Daten gesammelt ist?

+0

möglich Duplikat [Bash Rohr Handhabung] (http://stackoverflow.com/questions/19122/bash-pipe-handling) – devnull

+0

Siehe auch [this] (http://stackoverflow.com/questions/10031344/why-is-this-pipe-terminiert). – devnull

+0

Wenn Sie es wirklich brauchen, um zu hängen, verwenden Sie 'yes | Schwanz ". :-) –

Antwort

5

Wenn Sie sagen, yes | head die Schale Dinge ordnen, so dass der Ausgang des yes zu einem pipe geht und die Eingabe von head kommt aus dem gleichen Rohr. Wenn head 10 Zeilen liest, schließt es sein STDIN_FILENO und schließt dadurch sein Ende der Pipe. Wenn yes versucht, in eine geschlossene Pipe zu schreiben, wird eine SIGPIPE erhalten, deren Standardaktion es ist, sie zu beenden.

Ein einfacher Weg, dies zu testen ist mit strace:

$ strace yes | head 
y 
[...] 
y 
write(1, "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 4096) = -1 EPIPE (Broken pipe) 
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=4069, si_uid=1000} --- 
+++ killed by SIGPIPE +++ 
+0

Die Option '-f' macht dort nichts Sinnvolles. Es sieht wie ein Versuch aus, sowohl "ja" als auch "head" zu verfolgen, aber das tut es nicht, weil "strace" keine spezielle eingebaute Shell ist, die eine ganze Pipeline sehen kann. –

+0

@ WumpusQ.Wumbley Ich wollte nicht beide verfolgen; 'strace -f' ist nur ein Reflex, den ich aufgeschnappt habe. Ich habe es entfernt, guter Ruf :-) – cnicutar

4

das System sammelt alle das Ergebnis von ja und dann Rohren es

Kopf, extrem ineffizient wäre. Wenn Sie eine Pipe verwenden, erstellt das Betriebssystem einen Puffer für die Pipe-Kommunikation.

send | receive 

Solange es in dem Puffer der Sendeprozess in es schreiben genügend Platz ist, und wenn es genug Daten im Puffer ist, wird der Empfänger es verarbeiten. Wenn nicht, ist der Wartevorgang blockiert.

Sobald head beendet, dass die OS merkt es beendet, es wird ein Signal (SIGPIPE) auslösen, die den Sendevorgang wird beendet (es sei denn, der Prozess es Griffe).

+2

Der letzte Absatz ist skizzenhaft. Das Betriebssystem sendet das Signal nicht, sobald der Kopf fertig ist. Wenn der Kopf fertig ist, schließt das OS die Leseseite des Rohrs. Wenn "Ja" neu geplant wird, wird (letztendlich) versucht, in das Rohr zu schreiben, an welchem ​​Punkt das Signal angehoben wird. Betrachte den Unterschied zwischen 'yes>/dev/null | wahr 'und' ja | wahr '. –

Verwandte Themen