Книга: UNIX — универсальная среда программирования
3.7 Еще раз о переключении ввода-вывода
3.7 Еще раз о переключении ввода-вывода
Понятие стандартного потока диагностики было введено для того, чтобы сообщения об ошибках всегда появлялись на терминале:
$ diff file1 file2 >diff.out
diff: file2: No such file or directory
$
Без сомнения, сообщения об ошибке должны появляться подобным образом — было бы крайне неприятно, если бы они исчезли в файле diff.out
, оставляя вас в уверенности, что ошибочная команда diff
выполнена правильно.
В начале выполнения каждой программы определены по умолчанию три файла, обозначаемые небольшими целыми числами и называемые дескрипторами файла (мы рассмотрим их в гл. 7). Со стандартными входным (0) и выходным (1) потоками вы уже знакомы: они часто переключаются на файл или программный канал. Последний поток с номером 2 представляет собой стандартный поток диагностики и обычно предназначается для вывода на терминал.
Иногда программы осуществляют вывод в стандартный поток диагностики, даже если они работают правильно. Типичным примером является программа time, которая выполняет команду и выдает в стандартный поток диагностики сообщение о том, сколько времени заняло выполнение:
$ time wc ch3.1
931 4288 22691 ch3.1
real 1.0
user 0.4
sys 0.4
$ time wc ch3.1 >wc.out
real 2.0
user 0.4
sys 0.3
$ time wc ch3.1 >wc.out 2>time.out
$ cat time.out
real 1.0
user 0.4
sys 0.3
$
Конструкция 2> имя_файла
(между 2
и >
не должно быть пробелов) переключает стандартный поток диагностики на файл; синтаксически она непривлекательна, но служит своей цели. (Для такого короткого теста, как приведенный выше, время, выдаваемое командой time
, не совсем правильное, но для последовательности больших тестов она выводит полезную информацию, которой можно доверять в разумных границах. Вы вполне можете сохранить ее для дальнейшего анализа; обратитесь, например, к таблице 8.1.)
Допустимо также слияние двух выходных потоков:
$ time wc ch3.1 >wc.out 2>&1
$ cat wc.out
931 4288 22691 ch3.1
real 1.0
user 0.4
sys 0.3
$
Обозначение 2>&1
является указанием интерпретатору, что стандартный поток диагностики нужно поместить в тот же поток, что и стандартный выходной. Амперсанд не содержит какого-либо мнемонического смысла; это просто идиома, которую следует запомнить. Для добавления стандартного выходного потока к стандартному потоку диагностики можно использовать 1>&2
:
echo ... 1>&2
В командных файлах это позволяет предотвратить исчезновение сообщений в файле или программном канале.
Интерпретатор предоставляет возможность размещать стандартный входной поток вместе с командой, а не в отдельном файле, так что командный файл может хранить всю информацию в себе самом. Наша справочная программа 411
, работающая с каталогом телефонов, могла быть задана так:
$ cat 411
grep "$*" <<End
dial-a-joke 212-976-3838
dial-a-prayer 212-246-4200
dial santa 212-976-3636
dow jones report 212-976-4141
End
$
Программирующие на языке shell
называют такую конструкцию "документ здесь", т.е. входной поток находится здесь, а не в каком-нибудь файле. Началом конструкции служит <<
; последующее слово (в нашем примере End
) является ограничителем входного потока, включающего все строки до той, которая содержит только данное слово. Интерпретатор выполняет замену конструкций $
, `...`
и в "документе здесь", если только часть слова не экранирована кавычками или обратной дробной чертой, — в этом случае весь документ берется без изменений. В конце главы мы рассмотрим еще более интересный пример с конструкцией "документ здесь".
В табл. 3.2 перечислены различные виды переключения ввода-вывода, допускаемые интерпретатором.
> файл |
Переключение стандартного выходного потока в файл |
>> файл |
Добавление стандартного выходного потока в файл |
< файл |
Получение стандартного выходного потока из файла |
p1 | p2 |
Передача стандартного выходного потока программы p1 в качестве входного потока для программы p2 |
^ |
Устарелый синоним | |
n> файл |
Переключение выходного потока из файла с дескриптором n в файл |
n>> файл |
Добавление выходного потока из файла с дескриптором n в файл |
n>&m |
Слияние выходных потоков файлов с дескрипторами n и m |
<<s |
"Документ здесь": берется стандартный входной поток до строки, начинающейся с s; выполняется подстановка для $ , `...` и |
<<s |
"Документ здесь" без подстановки |
<<'s' |
"Документ здесь" без подстановки |
Таблица 3.2: Переключение ввода-вывода интерпретатора
Упражнение 3.14
Сравните версии программы 411: использующую "документ здесь" и первоначальную. Какую легче сопровождать? Какая более подходит в качестве основы общего служебного средства?
- 3.1 Структура командной строки
- 3.2 Метасимволы
- 3.3 Создание новых команд
- 3.4 Аргументы и параметры команд
- 3.5 Результат выполнения программы в качестве аргумента
- 3.6 Переменные языка shell
- 3.7 Еще раз о переключении ввода-вывода
- 3.8 Циклы в shell-программах
- 3.9 Программа bundle: соберем все воедино
- 3.10 Для чего нужно программировать на языке shell!
- От исключительной полезности к стратегическому ценообразованию
- Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
- Решетка «упразднить – снизить – повысить – создать»
- Миграция между различными версиями InterBase
- 4.7. Игровые разминки и упражнения-энергизаторы
- Совместимость клиентов и серверов различных версий
- Выбор стратегии ценообразования
- Преобразование XML в реляционную базу данных
- 1.1.4. Еще немного терминов
- Размер страницы базы данных
- Разрушаем легенду
- Раздача прав