[Из песочницы] Linux pipes tips & tricks
Pipe — что это? Pipe (конвеер) — это однонаправленный канал межпроцессорного взаимодействия. Термин был придуман Дугласом Макилроем для командной оболочки Unix и назван по аналогии с трубопроводом. Конвейеры чаще всего используются в shell-скриптах для связи нескольких команд путем перенаправления вывода одной команды (stdout) на вход (stdin) последующей, используя символ конвеера »|»: cmd1 | cmd2 | … | cmdN Например:$ grep -i «error» ./log | wc -l 43 grep выполняет регистронезависимый поиск строки «error» в файле log, но результат поиска не выводится на экран, а перенаправляется на вход (stdin) команды wc, которая в свою очередь выполняет подсчет количества строк.Логика Конвеер обеспечивает асинхронное выполнение команд с использованием буферизации ввода/вывода. Таким образом все команды в конвейере работают параллельно, каждая в своем процессе. Размер буфера начиная с ядра версии 2.6.11 составляет 65536 байт (64Кб) и равен странице памяти в более старых ядрах. При попытке чтения из пустого буфера процесс чтения блокируется до появления данных. Аналогично при попытке записи в заполненный буфер процесс записи будет заблокирован до освобождения необходимого места. Важно, что несмотря на то, что конвейер оперирует файловыми дескрипторами потоков ввода/вывода, все операции выполняются в памяти, без нагрузки на диск. Вся информация, приведенная ниже, касается оболочки bash-4.2 и ядра 3.10.10.Простой дебаг Утилита strace позволяет отследить системные вызовы в процессе выполнения программы:$ strace -f bash -c »/bin/echo foo | grep bar» … getpid () = 13726 <– PID основного процесса ... pipe([3, 4]) <– системный вызов для создания конвеера .... clone(....) = 13727 <– подпроцесс для первой команды конвеера (echo) ... [pid 13727] execve("/bin/echo", ["/bin/echo", "foo"], [/* 61 vars */] ..... [pid 13726] clone(....) = 13728 <– подпроцесс для второй команды (grep) создается так же основным процессом ... [pid 13728] stat("/home/aikikode/bin/grep", ... Видно, что для создания конвеера используется системный вызов pipe(), а также, что оба процесса выполняются параллельно в разных потоках.Читать дальше →