b8c4c21f

Конвейер


Нередко возникают ситуации, когда нужно обработать вывод одной программы какой-то другой программой. Пользуясь перенаправлением ввода-вывода, можно сохранить вывод одной программы в файле, а потом направить этот файл на ввод другой программе. Однако то же самое можно сделать и более эффективно: перенаправлять вывод можно не только в файл, но и непосредственно на стандартный ввод другой программе. В этом случае вместо двух команд потребуется только одна - программы передают друг другу данные "из рук в руки". В Linux такой способ передачи данных называется конвейер.

В bash для перенаправления стандартного вывода на стандартный ввод другой программе служит символ "|". Самый простой и наиболее распространенный случай, когда требуется использовать конвейер, возникает, если вывод программы не умещается на экране монитора и очень быстро "пролетает" перед глазами, так что человек не успевает его прочитать. В этом случае можно направить вывод в программу просмотра (less), которая позволит не торопясь пролистать весь текст, вернуться к началу и т. п.:

[methody@localhost methody]$ cat cat.info | less

Пример 7.9. Простейший конвейер (html, txt)

Можно последовательно обработать данные несколькими разными программами, перенаправляя вывод на ввод следующей программе и организуя сколь угодно длинный конвейер для обработки данных. В результате получаются очень длинные командные строки вида "cmd1 | cmd2 | ... | cmdN", которые могут показаться громоздкими и неудобными, но оказываются очень полезными и эффективными при обработке большого количества информации, как мы увидим далее в этой лекции.

Организация конвейера устроена в shell по той же схеме, что и перенаправление в файл, но с использованием особого объекта системы - канала. Если файл можно представить в виде коробки с данными, снабженной клапаном для чтения или клапаном для записи, то канал - это оба клапана, приклеенные друг к другу вообще без коробки. Для определенности между клапанами можно представить трубу, немедленно доставляющую данные от входа к выходу (английский термин - "pipe" - основан как раз на этом представлении, а в роли трубы выступает, конечно же, сам Linux). Каналом пользуются сразу два процесса: один пишет туда, другой читает. Связывая две команды конвейером, shell открывает канал (заводится два дескриптора - входной и выходной), подменяет по уже описанному алгоритму стандартный вывод первого процесса на входной дескриптор канала, а стандартный ввод второго процесса - на выходной дескриптор канала. После чего остается запустить по команде в этих процессах, и стандартный вывод первой попадет на стандартный ввод второй.

Канал (pipe) - неделимая пара дескрипторов (входной и выходной), связанных друг с другом таким образом, что данные, записанные во входной дескриптор, будут немедленно доступны на чтение с выходного дескриптора.



Содержание раздела