$ cat /etc/passwd | awk -F: '{print $1}' | sort > sort.out

Опция -f программы awk свидетельствует о том, что указанный после нее символ двоеточия является разделителем полей в файле /etc/passwd.

В один и тот же файл в режиме присоединения можно направлять результаты работы сразу нескольких команд:

$ ls -l | grep ^d >> files.out

$ 1s account* >> files.out

В первой строке в файл files.out помещается список каталогов, а во второй -cписок файлов, имена которых начинаются со строки "account".

Для создания пустого файла нулевой длины выполните следующую команду:

$ > myfile

5.7.2. Переадресация стандартного потока ввода

Рассмотрим несколько примеров переадресации стандартного потока ввода. Чтобы из командной строки отправить пользователю электронное сообщение, которое находится в файле, следует направить файл программе mail. Посредством следующей команды пользователь louise получит сообщение, которое содержится в файле contents.txt.

$ mail louise < contents.txt

Переадресация вида команда << разделитель называется конструкцией "документ здесь". Более подробно мы поговорим о ней позже. Пока же рассмотрим общие принципы ее функционирования. Встречая в командной строке оператор «, интерпретатор shell воспринимает все данные, вводимые с клавиатуры, как входной поток, пока в отдельной строке не будет введено слово–разделитель, указанное в командной строке после оператора. Разделителем может служить любое слово. Вот как, например, можно создать файл в режиме командной строки:

$ cat >> myfile << Пока

> Привет! Я работая за терминалом $TERM

и мое имя $LOGNAME.

Пока!

Пока

$ cat myfile

Привет! Я работаю за терминалом vt100

и мое имя dave.

Пока!

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

5.7.3. Переадресация стандартного потока ошибок

При переадресации стандартного потока ошибок указывается дескриптор 2. Рассмотрим пример. Утилита grep ищет в файле missiles строку "trident":

$ grep "trident" missiles

grep: missiles: No such file or directory

Однако в текущем каталоге нет такого файла, и соответствующее сообщение об ошибке по умолчанию выводится на экран. Можно переслать все сообщения об ошибках в системную корзину (устройство /dev/null):

$ grep "trident" missiles 2> /dev/null

Теперь никакие сообщения на экране отображаться не будут.

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

$ grep "trident" missiles 2> grep.err

$ cat grep.err

grep: missiles: No such file or directory

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

$ grep "LPSO" * 2>> account.err

$ grep "SILO" * 2>> account.err

5.7.4. Переадресация обоих выходных потоков

В одной командной строке можно последовательно переадресовывать как стандартный поток вывода, так и стандартный поток ошибок. Ниже приведен пример, в котором команда cat обрабатывает два файла, направляя вывод в файл accounts.out, а сообщения об ошибках — в файл accounts.err.

$ cat account_qtr.doc account_end.doc 1> accounts.out 2> accounts.err

$ cat accounts.out

AVBD 34HJ OUT AVFJ 31KO OUT

$ cat accounts.err

cat: account_end.doc: No such file or directory

Просмотрев файл accounts.err, обнаруживаем, что исходного файла account_end.doc не существует.

5.7.5. Объединение выходных потоков в файле

Оператор n>&m позволяет перенаправить файл с дескриптором n туда, куда направлен файл с дескриптором m. Подобных операторов в командной строке может быть несколько, в этом случае они вычисляются слева направо. Рассмотрим пример:

$ cleanup > cleanup.out 2>&1

Здесь сценарий cleanup направляет все свои выходные данные (как поток вывода, так и поток ошибок) в файл cleanup.out.

В следующем примере все результаты работы команды grep направляются в файл grep.out.

$ grep "standard" * > grep.out 2>&1

5.8. Команда exec

Команда exec заменяет текущий интерпретатор shell указанной командой. Обычно она используется для того, чтобы закрыть текущий интерпретатор и запустить другой. Но у нее есть и другое применение. Например, команда вида

exec < файл

делает указанный файл стандартным входным потоком всех команд. Выполнять ее в интерактивном режиме нет смысла -oна предназначена для использования в сценариях, чтобы все идущие после нее команды читали свои входные данные из файла. В этом случае в конце сценария обязательно должна стоять команда

exec <&-

которая закрывает стандартный входной поток (в данном случае файл). Подобный прием применяется преимущественно в сценариях, выполняющихся при выходе из системы. Более общий способ использования команды exec описан в следующем параграфе.

5.9. Применение дескрипторов файлов

Рассмотренная в предыдущем параграфе команда 'exec < файл' не только назначает файл стандартным входным потоком всех команд сценария, но и перезаписывает указатель на файл с дескриптором 0 (stdin). Восстановить этот указатель можно будет только по завершении работы сценария. Если же в сценарии предполагается продолжить чтение данных с клавиатуры, то необходимо каким‑то образом сохранить указатель на прежний входной поток. Ниже приведен небольшой сценарий, в котором демонстрируется, как это сделать.

$ cat f_desc

#!/bin/sh

# f_desc

exec 3<&0 0<stock.txt

read line1

read line2

exec 0<&3

echo $LINEl

echo $LINE2

Первая команда exec сохраняет указатель на стандартный входной поток (stdin) в файле с дескриптором 3 (допускается любое целое число в диапазоне от 3 до 9), а затем открывает файл stock.txt для чтения. Следующие две команды read читают из файла две строки текста. Вторая команда exec восстанавливает указатель на стандартный входной поток: теперь он связан с файлом stdin, а не stock.txt. Завершающие команды echo отображают на экране содержимое прочитанных строк, которые были сохранены в переменных line1 и line2.

Предположим, файл stock.txt содержит такой текст:

$ cat stock.txt

Crayons Assorted 34

Pencils Light 12

Ниже показаны результаты работы сценария:

$ f_desc

Crayons Assorted 34

Pencils Light 12

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

5.10. Заключение

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

ГЛАВА 6

Порядок выполнения команд

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


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