$ who > temp

$ wc -l < temp

и число файлов в текущем каталоге:

$ ls > temp

$ wc -l < temp

хотя в это число войдет и сам файл

temp
. Можно выдать список имен файлов в три столбца, задав

$ ls > temp

$ pr -3 < temp

Наконец, можно убедиться в том, что некий пользователь вошел в систему, комбинируя команды

who
и
grep
:

$ who > temp

$ grep mary < temp

Во всех перечисленных выше примерах, как и в случае имен файлов, содержащих образы типа

*
, важно понимать, что символы
<
и
>
обрабатываются самим интерпретатором
shell
, а не отдельной программой. Благодаря этому переключение входного и выходного потоков возможно для любой программы, причем сама программа даже "не подозревает", что происходит что-то необычное.

Изложенное подводит нас к важному выводу. Команда

$ sort < temp

сортирует содержимое файла

temp
так же, как

$ sort temp

но в их действиях есть различие. Поскольку строка

< temp
обрабатывается интерпретатором
shell
, первая команда
sort
не воспринимает файл
temp
как свой аргумент; она просто сортирует собственный стандартный входной поток, который переключен интерпретатором на файл
temp
. В то же время в последнем случае имя temp передается команде sort в качестве аргумента, она читает его и сортирует файл. Команде sort можно передать список файлов:

$ sort temp1 temp2 temp3

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

$ sort

ghi

abc

def

ctl-c

abc

def

ghi

$

В дальнейшем мы покажем, как реализуется этот принцип.

Упражнение 1.5

Объясните, почему команда

$ ls > ls.out

включает

ls.out
в список имен.

Упражнение 1.6

Объясните результат выполнения команды

$ wc temp > temp

Что произойдет, если вы ошибетесь в имени команды, задав

$ woh > temp

Программные каналы

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

Пересмотрим теперь некоторые из предыдущих примеров с точки зрения использования программных каналов вместо временных файлов. Вертикальная черта служит указанием интерпретатору

shell
для создания конвейера:

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

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

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

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

$ who | grep mary
Поиск определенного пользователя

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

pr
,
grep
,
sort
и
wc
используются именно таким способом.

Можно связать конвейером сколь угодно много программ. Например,

$ ls | pr -3 | lpr

создает список имен файлов в три столбца и выдает его на печатающее устройство, а

$ who | grep mary | wc -l

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

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

<i>команда флаги возможные имена файлов</i>

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

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

UNIX — универсальная среда программирования img_2.jpeg

Рис. 1.2: Схема потоков в UNIX

Почти все рассматривавшиеся выше команды укладываются в эту схему; исключение составляют

who
и
date
, не имеющие входной информации, а также те, например
cmp
или
diff
, которые имеют определенное число входных файлов. (Посмотрите их флаг
'-'
.)


Перейти на страницу:
Изменить размер шрифта: