во время чтения, grep, pipe и зависания

во время чтения, grep, pipe и зависания
yes "test" | grep -m3 "test"

отпечатки

test
test
test

и затем прекращается. Так же

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

и

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

Но

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

отпечатки

test
test
test

и тут же зависает. Что тут происходит?

решение1

В

да "тест" | пока читается строка; сделать echo $line; готово | grep -E "*" | grep -m3 "тест"
есть четыре процесса, запущенных yes, программа оболочки, запускающая этот whileцикл, grep, и grepсоответственно. Последний процесс в конвейере завершается, закрывая конец чтения своего входного канала, после трех совпадений. Затем конвейер завершается цепочкой SIGPIPEs обычным способом для преждевременно завершенных конвейеров, поскольку каждая стадия конвейера в свою очередь завершает запись в сломанный канал.

В

да "тест" | пока читается строка; сделать echo $line | grep -E "*"; готово | grep -m3 "тест"
есть три запущенных процесса yes, программа оболочки, и grepсоответственно. Но второй процесс, который запускает программу оболочки, постоянно порождает двадальшедочерние процессы, один из которых выполняет echoи другой запускает другой grepэкземпляр. Именно этот последний процесс получает SIGPIPEинетпроцесс запуска программы оболочки. Именно этот последний процесс, в конце концов, на самом деле пишет в сломанный канал.

Следствием этого является то, что вторая ступень трубопровода, оболочка, управляющая этим whileконтуром, никогда несамзавершается с SIGPIPEи просто продолжает работать, порождая дочерний конвейер; снова и снова. Он видит, что дочерний конвейер, который он породил, завершается с конечно SIGPIPE, но для оболочки, выполняющей whileцикл, которыйнетпричина для прекращения цикла.

Связанный контент