Главная » Программирование для UNIX » Программные каналы UNIX

0

Во  всех  примерах предыдущего раздела  применялся один  и  тот  же прием: помещение вывода одной программы на вход другой через временный файл. Но ведь у временного файла нет другого назначения; на самом  деле это слишком грубый метод. Данное наблюдение привело к созданию концепции программного канала (pipe),  одного  из наиболее важных достижений системы UNIX. Канал – это способ подключения вывода одной  программы на вход другой без каких бы то ни было временных файлов; а конвейер (pipeline) – это соединение двух  или  более программ посредством каналов.

Давайте обратимся к примерам, рассмотренным ранее, и используем каналы вместо  временных файлов. Символ вертикальной черты | сообщает  оболочке, что надо образовать конвейер:

$ who  | sort               Печатает отсортированный список пользователей

$ who  | wc -l        Считает количество пользователей

$ ls | wc -l         Считает количество файлов

$ ls | pr  -3               Выводит имена файлов в 3 колонки

$ who  | grep  mary     Ищет указанного пользователя

Любая программа, которая читает с терминала, может читать вместо  этого из канала; любая программа, которая выводит данные на терминал, может выводить их в канал. Именно в этой ситуации соглашение о том, что  если  программе  не  указаны имена файлов, то она  читает стандартный ввод,  окупается в полной мере:  все программы, соблюдающие  это  соглашение, могут  быть  включены в  конвейеры. В примерах, рассмотренных выше, команды grep, pr, sort и wc используются в конвейерах именно таким образом.

В конвейер можно включить любое количество программ:

$ ls | pr  -3  | lpr

создает список файлов в 3 колонки на построчно печатающем принтере, а

$ who  | grep  mary | wc -l

подсчитывает, сколько раз Мэри зарегистрирована в системе.

В действительности все программы конвейера выполняются одновременно, а не одна за другой. Это означает, что программа конвейера может  быть и интерактивной; ядро  следит за тем, как правильно обеспечить  синхронизацию и диспетчеризацию, чтобы все работало.

Как  вы, наверное, уже  догадываетесь, созданием каналов занимается оболочка; отдельные программы не имеют понятия о перенаправлении ввода-вывода. Конечно, для того чтобы иметь возможность совместной работы, программы должны придерживаться определенных соглашений. Большинство команд имеет  одинаковый дизайн, так  что они подходят для любой  позиции в конвейере. Обычно  вызов программы выглядит следующим образом:

команда необязательные5аргументы необязательные5имена5файлов

Если  имена файлов не указаны, то команда читает свой  стандартный ввод, который по умолчанию является терминалом (удобно для экспериментов), но может перенаправляться и поступать из файла или  ка нала. Что  же касается вывода, большая часть  команд направляет его на стандартный вывод, который по умолчанию связан с терминалом, но и он также может быть перенаправлен в файл или канал.

А вот  сообщения об ошибках исполнения  команд должны обрабатываться по-другому, иначе они могут исчезнуть в файле или канале. Поэтому у каждой команды есть еще и стандартный вывод  ошибок, который  обычно направляется на терминал. Схема  на рис.  1.2 иллюстрирует весь процесс.

Практически все команды, описанные ранее, работают по этой  модели; исключение составляют такие команды, как date и who, которые не читают входные данные, и несколько команд типа  cmp и diff, у кото рых фиксированное количество входных файлов. (Но обратите внимание на параметр «–» в этих командах.)

Рис. 1.2. Обработка сообщений об ошибках

Упражнение 1.7. Объясните, в чем состоит отличие между

$ who  | sort

и

$ who  >sort

~

Источник: Керниган Б., Пайк Р., UNIX. Программное окружение. – Пер. с англ. – СПб: Символ-Плюс, 2003. – 416 с., ил.

По теме:

  • Комментарии