podczas czytania, grep, fajki i powieszenia

3
yes "test" | grep -m3 "test"

odbitki

test
test
test

a następnie kończy się. Tak też jest

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

i

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

Ale

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

odbitki

test
test
test

a następnie zawiesza się. Co tu się dzieje?

Robby McKilliam
źródło
To nie jest greprzecz, ponieważ widać to samo zawieszenie yes "test" | while read line; do echo $line | cat; done | head -3. Usuń | cati nie zawiesza się.
agc
1
A jeśli to zrobisz set -x, zobaczysz, że pętla działa znacznie więcej niż 3 razy we wszystkich przypadkach (prawdopodobnie wystarczająca do opróżnienia bufora w przypadkach, w których umiera).
mur

Odpowiedzi:

7

W

tak „test” | podczas odczytu linii; wykonaj echo $ line; zrobione | grep -E "*" | grep -m3 „test”
uruchomione są cztery procesy, yesprogram powłoki działający w tej whilepętli grepi grepodpowiednio. Ostatni proces w potoku kończy się, zamykając czytany koniec potoku wejściowego po trzech dopasowaniach. Rurociąg kończy się następnie łańcuchem SIGPIPEs w zwykły sposób dla rurociągów przedwcześnie zakończonych, ponieważ każdy etap rurociągu z kolei kończy się zapisem na zepsutej rurze.

W

tak „test” | podczas odczytu linii; wykonaj echo $ line | grep -E "*"; zrobione | grep -m3 „test”
działają trzy procesy yes, odpowiednio program powłoki grep. Ale drugi proces, ten, w którym uruchomiony jest program powłoki, nieustannie odradza dwa kolejne procesy potomne, jeden wykonujący, echoa drugi uruchamiający inną grepinstancję. To ten ostatni proces jest wysyłany, SIGPIPEa nie proces uruchamiający program powłoki. Jest to ten ostatni proces, który w rzeczywistości polega na pisaniu na zepsutej rurze.

Konsekwencją tego jest to, że drugi etap potoku, powłoka działająca w tej whilepętli, nigdy sam się nie kończy SIGPIPEi po prostu działa dalej, odradzając potok potomny; raz po raz. Widzi, że potok potomny, który się pojawił, kończy się SIGPIPEoczywiście, ale dla powłoki działającej w whilepętli, która nie jest powodem do zakończenia pętli.

JdeBP
źródło