Система ввода и вывода

Команды и утилиты операционной системы Unix вводятся с клавиатуры, а

результаты их выполнения выводятся на дисплей терминала, которые часто называют

стандартными устройствами ввода/вывода. Некоторых команды, такие как pr или mail

перехватывают вывод на стандартные устройства и посылают данные в файл или на

устройство печати. Unix не только обеспечивает эту возможность, но и позволяет

соединять команды таким образом, чтобы канал вывода одной команды был связан с

каналом ввода другой.

Когда программа вызывается на исполнение, создается процесс, который

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

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

Когда процесс запускается, всегда три дескриптора для него являются открытыми - они

открываются процессом-родителем текущего процесса (например, процессом shell):

- канал стандартного ввода;

- канал стандартного вывода;

- канал стандартного вывода сообщений об ошибках.

Введите команду cat без аргументов. Обратите внимание на курсор. Наберите

несколько строк текста, используя клавишу <Enter>.Что происходит? Нажатие клавиш

<Ctrl>dзавершит выполнение команды и вернет управление процессу shell.

Направление потока вводимых или выводимых данных может быть изменено таким

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

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

вместо дисплея терминала.

Оболочки Unix, такие как Bourne shell (sh), Korn shell (ksh) или C shell (csh)

обеспечивают возможность перенаправления стандартного ввода, стандартного вывода и

стандартного вывода сообщений об ошибках. Это достигается путем использование

специальных синтаксических конструкций в командной строке. Важно, что все оболочки

устанавливают признак перенаправления ввода/вывода перед выполнением команды. В

результате команда даже "не знает", что это имело место, и что stdout будет ссылаться на

файл вместо терминала. Здесь следует напомнить, что процесс обычно имеет два

дескриптора файла, stdout и stderr и оба они ссылаются на дисплей терминала. Зачем два

дескриптора относятся к одному устройству? Смысл этого заключается в том, что stderr

обычно не требует перенаправления, поскольку все диагностические сообщения могут

быть очень важны для пользователя. Однако если у пользователя есть необходимость в

перенаправлении stderr, он также имеет возможность сделать это, с помощью shell.

В командной строке канал stdout можно перенаправить, используя метасимвол >,

следующим образом:

команда> имя_файла

команда1>имя_файла

Имя файла должно быть указано непосредственно после символа >, пробел между

ними необязателен.

Номер дескриптора указывается непосредственно перед символом >, пробел между

ними не допускается. Если номер дескриптора опущен, по умолчанию его номер - 1.

Символ перенаправления и, связанное с ним имя файла, могут быть в любом месте

командной строки, однако такую синтаксическую конструкцию принято помещать в

конце командной строки.

Например, для решения задачи объединения содержимого файлов /etc/passwd и

/etc/group и сохранение результата в файле mix следующие _________командные строки будут

эквивалентны:

$ cat /etc/passwd /etc/group >mix

$ cat >mix /etc/passwd /etc/group

Если файл, имя которого указано после символа перенаправления не существует, то

он сначала создается оболочкой, а затем в него будет перенаправляться вывод.

Если файл уже существует, то его содержимое уничтожается и замещается выводом

выполняемой команды.

Перенаправление ввода/вывода в командной строке может быть определено без

имени команды. В этом случае shell создаст пустой файл или удалит содержимое

существующего файла с указанным именем.

$ >filename

Перенаправление стандартного вывода сообщений об ошибках stderr реализуется

тем же путем, что и для stdout, т.е. использованием символа > в командной строке:

команда2>имя_файла

Номер дескриптора указывается непосредственно перед символом >, пробел между

ними не допускается. В отличие от stdout, номер дескриптора стандартного вывода

сообщений об ошибках – 2, должен обязательно указываться перед символом

перенаправления.

Сохраненные в файле сообщения могут быть в дальнейшем использованы для

анализа ситуации, вызвавшей ошибку в программе.

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

stdout и stderr:

команда1> имя_файла1 2> имя_файла2

Имеется возможность перенаправить stdout и stderr в один и тот же файл. Для этого

необходимо использовать специальное обозначение:

команда > имя_файла 2>&1

2>&1 в данном случае означает следующее: перенаправить stderr туда же, куда был

направлен stdout (&1)

Выполните команду:

$ find / -name fff >fff_file 2>errors

Где находятся сообщения об ошибках?

Что будет сделано следующей командой?

$ find . 2>error_file >2 &

Обычное перенаправление бывает разрушительным для существующего файла. Из

предыдущего материала видно, что содержимое файла заменяется или удаляется. Shell

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

данными.

Символ дополнения (>>) используется для ввода новых данных, которые будут

размещаться в конце существующего файла.

Для stdout используется синтаксическая конструкция:

command >> filename

command 1>> filename

Для stderr используется следующий синтаксис:

command 2>> filename

Если имя файла filename не существует, файл создается.

Введите командную строку

$ cal > cal_out

Дополните файл cal_out данными, которые выводит команда date.

Перенаправление ввода позволяет программам получать данные из файла вместо

стандартного ввода по умолчанию (клавиатуры терминала).

Для перенаправления stdin в командной строке используется метасимвол (<):

команда < имя_файла

команда 0< имя_файла

Если номер дескриптора опущен, по умолчанию принимается значение 0.

Перенаправление stdin используется гораздо реже, чем перенаправление stdout или

stderr, потому что большинство команд открывают файлы (с дескрипторами, отличными

от 0,1 или 2) самостоятельно. Однако если они только читают из stdin, перенаправление

ввода может быть особенно полезным.

Приведенные ниже команды дают одинаковый результат, однако, они отличаются

друг от друга:

$ cat text

$ cat < text

Первая команда cat открывает файл text и определяется новый дескриптор файла.

Вторая команда cat использует stdin, который был связан оболочкой ссылкой к файлу

text.

$ more myfile

$ more < myfile

В первом примере команда more открывает файл myfile и определяет новый

дескриптор файла. Во втором примере more использует stdin, который был связан

оболочкой с файлом myfile. Здесь можно увидеть различие в действиях, когда more

открывает файл и когда использует stdin: строка состояния в нижней части экрана не

отображает процент просмотренной части файла в том случае, когда команда more читает

данные из stdin.

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

синтаксической конструкцией, используемой shell и командой tee операционной системы

Unix

Синтаксическая конструкция shell, которая позволяет создавать возможность

перенаправления потока со стандартного вывода одной команды на стандартный ввод

другой команды, называется конвейером команд. В отличие от обычного

перенаправления ввода/вывода, когда используется файл, конвейер реализует

непосредственную передачу данных из выходного потока данных одного процесса во

входной поток другого процесса.

Символ |(вертикальная черта) в командной строке указывает на перенаправление

стандартного вывода команды1 на стандартный ввод команды2:

команда1 | команда2

Команда1 должна записать выводные данные в stdout, а команда2 прочитать данные

из своего stdin. Надо заметить, что в конвейере нельзя использовать команды

(указываемые после символа вертикальная черта - |), которые не используют stdin,

(например, date или ps) и команды, использующие интерактивный режим работы, такие,

как vi или mail.

Каждая из команд в конвейере должна быть полностью определена, и содержать все

опции и аргументы, которые требуются для ее выполнения.

Следующие команды позволяют вывести на терминал информацию о числе

пользователей, работающих в настоящий момент:

$ who > tmpwho

$ wc –l tmpwho

$ rm tmpwho

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

следующего вида:

$ who | wc –l

В общем случае все команды, которые могут читать из stdin и писать в stdout

называются фильтрами.

Команды, которые не могут читать из stdin (например, date) или писать в stdout

(например, exit), и команды, использующие интерактивный режим работы (например, vi

или sh), не являются фильтрами.

Многие команды фильтры разработаны таким образом, что они могут читать по

умолчанию из stdin (например, sort или cat), но только в случае, когда в командной строке

не указано имени файла. Если имя файла указано, то команда открывает этот файл. Это

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

Команда wcподсчитывает число строк, слов и символов в текстовом файле:

wc[ -l | -w | -c ] [ file … ]

Строки файла определяются числом символов перевода строки.

Слова являются любым набором символов, они отделяются друг от друга символом

перевода строки, пробелом или знаком табуляции.

Следующая командная строка определяет число зарегистрированных пользователей

системы:

$ cat /etc/passwd | wc –l

$

Команда sortсортирует строки текстового файла, а затем результат записывает в

стандартный вывод. Строки вывода упорядочиваются в соответствии с содержащимися в

них символами (слева направо). Если указывается несколько файлов, то они сортируются

и сливаются. Для более подробного знакомства с опциями команды обратитесь к

соответствующей странице руководства.

sort[ options ] [ file …]

Как и любой другой фильтр sort не изменяет содержимого входного файла, а

результат записывает в stdout.

Следующая командная строка сортирует содержимое файл /etc/passwd, а на экран

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

$ sort /etc/passwd | nl

Команда trвыполняет трансляцию указанных символов файла, заменяя их новыми.

tr[ option ] строка1 строка2

Команда заменяет каждый символ набора строка1 соответствующими символами

набора строка2. При этом число символов строка2 (обычно) должно быть равно числу

символов строка1.

Тройникамиявляются команды фильтры, которые могут читать stdin, а писать

одновременно в stdout и в один или несколько файлов, указанных в командной строке.

Примером такой команды может служить команда tee:

tee[ options ] [file … ]

Команда teeне изменяет содержимого потока данных через stdin, а просто выводит

две или более копий, одна из которых направляется в stdout, а все остальные в другие

файлы; в том случае, если указанные файлы не существуют, команда создает их заново,

содержимое уже существующих файлов уничтожается. Опция –a используется для

добавления вывода в файлы без замены их содержимого.