Шрифт:
$ cat -v life.tct
ERROR ON REC A$12^M ERROR ON REC AS31^M
5.4. Каналы
Каналом называется способ переадресации данных, при котором результаты работы одной команды передаются другой команде в виде входных данных. Канал организуется с помощью оператора |:
команда1 | команда2
В следующем примере команда ls формирует список всех файлов из текущего каталога. Этот список был бы выведен на экран, если бы не символ канала. Интерпретатор shell обнаруживает канал, перехватывает все выходные потоки команды, стоящей слева от оператора [, и направляет их команде, которая расположена справа от оператора. В данном случае утилита фильтрации grep отбирает в списке файл с именем quarter1.doc:
$ ls | grep quarter1.doc
quarter1.doc
Представим этот пример схематически:
$ ls
Канал
grep quarter1.doc
| Выходные данные команды ls
$ ls accounts.doc acc_LPSO.doc quarter1.doc
quarter1.doc quarter2.doc
При обработке строковых данных можно объединять, каналами такие мощные программы фильтрации, как потоковый редактор sed, редактор awk и утилита grep, создавая сложные критерии отбора информации. В показанной ниже командной строке команда who выводит информацию о пользователях, зарегистрированных в
данный момент в системе, а программа awk выбирает из каждой строки имя пользователя (первое поле) и идентификатор терминала (второе поле):
$ who | awk '{print $1"\t"$2}'
matthew pts/0 louise pts/1
Следующая командная строка служит для вывода списка всех смонтированных файловых систем. Команда df формирует расширенный список с указанием всевозможных статистических данных об использовании каждой файловой системы. Программа awk извлекает из этого списка только первый столбец с именами файловых систем, а команда grep -v удаляет заголовок этого столбца, оставляя только имена.
$ df | awk '{print $1}' | grep -v "Filesystem"
/dev/hda5 /dev/hda8 /dev/hda6 /dev/hdb5 /dev/hdb1 /dev/hda7 /dev/hda1
С помощью редактора sed можно удалить из полученного списка повторяющуюся подстроку /dev/, оставив только имя раздела. Вот как это делается:
$ df | awk '(print $1}' | grep -v "Filesystem" | sed s'/\/dev\///g'
hda5 hdа8 hda6 hdb6 hdb1 hda7 hda1
Команда s редактора sed предназначена для замены указанного шаблона (в данном случае \/dev\/; символы '/' имеют специальное назначение, поэтому защищены символами \) заданной строкой (в нашем случае это пустая строка). Флаг g означает, что замену нужно производить каждый раз, когда обнаружено совпадение, а не только первый раз.
В следующем примере команда sort сортирует строки текстового файла myfile, а результат посылается на принтер:
$ sort myfile | lp
5.5. Команда tee
Команда tee функционирует следующим образом: входные данные копируются, при этом одна копия направляется в стандартный поток вывода, а другие копии — в указанные файлы. Общий формат этой команды таков:
tee [-a] файлы
Опция -a задает добавление выводимых данных в конец файла (по умолчанию производится замена содержимого файла). Команду tee удобно применять в том случае, когда необходимо вести журнал выводимых данных или сообщений.
Рассмотрим пример. Команда who формирует список пользователей, которые зарегистрированы в данный момент в системе, а команда tee отображает этот список на экране, направляя копию в файл who.out.
$ who | tee who.out
louise pts/l May 20 12:58 (193.132.90.9)
matthew pts/0 May 20 10:18 (193.132.90.1)
$ cat who.out
louise pts/1 May 20 12:58 (193.132.90.9) matthew pts/0 May 20 10:18 (193.132.90.1)
В следующем примере команда cpio выполняет резервирование файлов из каталога /home на магнитную ленту, а список помещаемых в архив файлов фиксируется в файле tape.log. Поскольку с помощью команды cpio производится последовательное добавление данных в архив, воспользуйтесь опцией '-a' команды tee:
$ find /home -depth -print | cpio -ov -0 /dev/rmt0 | tee -a tape.log
Чтобы сообщить пользователю о том, кто именно выполнил сценарий myscript, сохраняющий выводимые данные в файле myscript.log, можно перед вызовом сценарии задать несложную команду echo:
$ echo "Сценарий myscript запушен пользователем dave" | tee -a myscript.log $ myscript | tee -a myscript.log
Можно направлять вывод нескольких команд в один и тот же файл, но не забывайте применять опцию '-a'.
$ sort myfile | tee -a accounts.log $ myscript | tee -a accounts.log
5.6. Стандартные потоки ввода, вывода и ошибок
С каждым процессом (командой, сценарием и т. п.), выполняемым в интерпретаторе shell, связан ряд открытых файлов, из которых процесс может читать свои данные, и в которые он может записывать их. Каждый из этих файлов идентифицируется числом, называемым дескриптором файла, но у первых трех файлов есть также именам которые легче запоминать:
Файл