KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программное обеспечение » Брайан Керниган - UNIX — универсальная среда программирования

Брайан Керниган - UNIX — универсальная среда программирования

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Брайан Керниган, "UNIX — универсальная среда программирования" бесплатно, без регистрации.
Перейти на страницу:

$ rm *.save

удалит все файлы, оканчивающиеся на .save.

Заметьте, что все имена файлов выбираются в алфавитном порядке, который отличается от числового. Если в вашей книге 10 глав, порядок может быть не тем, на который вы рассчитываете, поскольку ch10 идет перед ch2:

$ echo *

ch1.1 ch1.2 ... ch10.1 ch10.2 ... ch2.1 ch2.2 ...

Символ * — не единственный способ задания шаблона для интерпретатора shell, хотя и наиболее часто используемый. Шаблон [...] задает любые символы из перечисленных внутри скобок. Несколько подряд следующих букв или цифр можно задать в сокращенном виде:

$ pr ch[12346789]* Печать глав 1,2,3,4,6,7,8,9, но не 5

$ pr ch[1-46-9]*   То же самое

$ rm temp[a-z]     Удалить все tempa, …, tempz

Шаблон ? задает любой одиночный символ:

$ ls ?        Список файлов с именем из одного символа

$ ls -l ch?.1 Список ch1.1 ch2.1 ch3.1 и т.д., но не ch10.1

$ rm temp?    Удалить все файлы temp1, …, tempa и т.д.

Отметим, что шаблоны сопоставляются только с именами существующих файлов. В частности, нельзя создать новые имена файлов с помощью шаблонов. Например, если вы захотите расширить ch до chapter в каждом имени файла, то такой вариант вам не поможет:

$ mv ch.* chapter.* Не работает!

поскольку chapter.* не соответствует ни одному из существующих имен файлов.

Символы шаблонов, подобные *, могут использоваться в абсолютных именах наравне с обычными именами файлов; сопоставление происходит для каждого компонента абсолютного имени, содержащего специальный символ. Так, /usr/mary/* инициирует поиск файлов в /usr/mary/, a /usr/*/calendar порождает список абсолютных имен всех пользователей, работающих с каталогом calendar.

Если вам когда-нибудь придется отказаться от специального назначения символов *, ? и др., заключите весь аргумент в апострофы, например:

$ ls '?'

Можно также предварить специальный символ обратной дробной чертой:

$ ls ?

(Вспомните, что, поскольку ? не является символом стирания или уничтожения, обратная дробная черта перед ним будет обрабатываться не ядром, а интерпретатором shell.) Использование кавычек подробно рассматривается в гл. 3.

Упражнение 1.4

В чем состоит различие между следующими командами:

$ ls junk  $ echo junk

$ ls /     $ echo /

$ ls       $ echo

$ ls *     $ echo *

$ ls '*'   $ echo '*'

Переключение ввода-вывода

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

Например,

$ ls

выдает список файлов на ваш терминал. Но если задать

$ ls > filelist

то тот же список файлов помещается вместо этого в файл filelist. Символ > означает, что выходной поток должен быть помещен в указанный далее файл, а не выведен на терминал. Файл будет создан, если он ранее не существовал, или будет заменено содержимое старого. На своем терминале вы ничего не получите. В качестве другого примера можно слить несколько файлов, "перехватив" выходной поток команды cat и направив его в файл:

$ cat f1 f2 f3 > temp

Символ >> действует подобно >, но указывает на необходимость добавить выходной поток к концу файла. Значит, команда

$ cat f1 f2 f3 >> temp

сольет содержимое f1, f2, f3 и добавит результат в конец temp, вместо того чтобы затереть его старое содержимое. Так же как и для операции >, если файл temp не существует, то он будет создан первоначально пустым.

Аналогично символ < означает, что входной поток программы берется из последующего файла, а не с терминала. Так, можно заготовить письмо в файле let, а затем послать его нескольким адресатам:

$ mail mary joe torn bob < let

Во всех этих примерах наличие пробелов по обе стороны символа > или < не обязательно, но такое представление традиционно.

Имея возможность переключать выходной поток с помощью <, мы можем комбинировать команды, получая эффект, недостижимый другим способом. Например, можно выдать список пользователей в алфавитном порядке

$ who > temp

$ sort < temp

Поскольку команда who выдает по одной строке на каждого пользователя, работающего в системе, a wc -l производит подсчет строк (подавляя вывод числа слов и символов), можно подсчитать число пользователей с помощью команд:

$ 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 используются именно таким способом.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*