während Lesen, Grep, Pipes und Hängen

während Lesen, Grep, Pipes und Hängen
yes "test" | grep -m3 "test"

druckt

test
test
test

und dann endet. Dasselbe gilt

yes "test" | while read line; do echo $line; done | grep -m3 "test"

Und

yes "test" | while read line; do echo $line; done | grep -E "*" | grep -m3 "test"

Aber

yes "test" | while read line; do echo $line | grep -E "*"; done | grep -m3 "test"

druckt

test
test
test

und bleibt dann hängen. Was ist hier los?

Antwort1

In

ja "testen" | während Zeile lesen; mache Echo $Zeile; fertig | grep -E "*" | grep -m3 "testen"
Es gibt vier Prozesse, die ausgeführt werden yes, das Shell-Programm, das diese whileSchleife ausführt, grepund grep. Der letzte Prozess in der Pipeline wird beendet und schließt das Leseende seiner Eingabepipe nach drei Übereinstimmungen. Die Pipeline wird dann durch eine Kette von SIGPIPEs beendet, wie es für vorzeitig beendete Pipelines üblich ist, da jede Stufe der Pipeline wiederum in eine defekte Pipe schreibt.

In

ja "testen" | während Zeile gelesen wird; mache echo $line | grep -E "*"; fertig | grep -m3 "testen"
Es laufen drei Prozesse yes, das Shell-Programm und grep. Aber der zweite Prozess, der das Shell-Programm ausführt, erzeugt ständig zweiweiteruntergeordnete Prozesse, einer führt die echound einer eine andere grepInstanz aus. Letzterer Prozess sendet die SIGPIPEundnichtder Prozess, der das Shell-Programm ausführt. Es ist dieser letztere Prozess, der tatsächlich in die defekte Pipe schreibt.

Die Folge davon ist, dass die zweite Stufe der Pipeline, die Shell, die diese whileSchleife ausführt, niemalsselbstbeendet SIGPIPEund läuft einfach weiter, wobei eine untergeordnete Pipeline erzeugt wird; immer und immer wieder. Es sieht, dass die untergeordnete Pipeline, die es erzeugt hat, SIGPIPEnatürlich mit einem endet, aber für die Shell, die die whileSchleife ausführt, ist dasnichtein Grund, die Schleife zu beenden.

verwandte Informationen