
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
соответственно. Последний процесс в конвейере завершается, закрывая конец чтения своего входного канала, после трех совпадений. Затем конвейер завершается цепочкой SIGPIPE
s обычным способом для преждевременно завершенных конвейеров, поскольку каждая стадия конвейера в свою очередь завершает запись в сломанный канал.
В
да "тест" | пока читается строка; сделать echo $line | grep -E "*"; готово | grep -m3 "тест"есть три запущенных процесса
yes
, программа оболочки, и grep
соответственно. Но второй процесс, который запускает программу оболочки, постоянно порождает двадальшедочерние процессы, один из которых выполняет echo
и другой запускает другой grep
экземпляр. Именно этот последний процесс получает SIGPIPE
инетпроцесс запуска программы оболочки. Именно этот последний процесс, в конце концов, на самом деле пишет в сломанный канал.
Следствием этого является то, что вторая ступень трубопровода, оболочка, управляющая этим while
контуром, никогда несамзавершается с SIGPIPE
и просто продолжает работать, порождая дочерний конвейер; снова и снова. Он видит, что дочерний конвейер, который он породил, завершается с конечно SIGPIPE
, но для оболочки, выполняющей while
цикл, которыйнетпричина для прекращения цикла.