Как оболочка выполняет команды с каналами?

Я хочу понять, как оболочка выполняет команды с каналами? например кошка | Больше. Я знаю, что для выполнения обычной командной оболочки вилка выполняет, а потом возвращает ребенка. Но как оболочка внутренне обрабатывает выполнение команд с каналами?

Ответ 1

Учитывая, например, cat | grep, оболочка сначала запускает начало cat, а затем снова запускает начало grep.

Прежде чем вызывать одно из семейств функций exec* в двух новых созданных процессах для запуска двух программ, сложной частью является настройка канала и перенаправление дескрипторов. Системный вызов pipe(2) используется в процессе оболочки перед форсированием, чтобы вернуть пару дескрипторов, которые наследуют оба дочерних элемента - конец чтения и конец записи.

Конец чтения будет закрыт в первом процессе (cat), а stdout будет перенаправлен на конец записи, используя системный вызов dup2(2). Точно так же конец записи во втором процессе (grep) будет закрыт, а stdin снова будет перенаправлен на конец считывания, используя dup2(2).

Таким образом, обе программы не знают о трубе, потому что они просто работают со стандартным вводом/выводом.

Ответ 2

Он устанавливает канал, используя системный вызов pipe, разворачивает два процесса вместо одного и присоединяет один конец канала к первый процесс 'stdout и другой конец второго процесса' stdin.