имеет ограничений по правам доступа к файлам. В этом случае возникает
проблема для системного администратора!

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


    ОТМЕТКИ О ВРЕМЕНИ ДОСТУПА К ТЕРМИНАЛУ



Еще одним атрибутом терминалов, который вызван тем, что терминалы
- это файлы, являются даты модификации, доступа и обновления. Каждый
файл в системе имеет эти три даты, которые содержатся в его индексном
дескрипторе (в секундах) в виде ДЛИННЫХ (long) чисел.

Эти даты могут содержать некоторую интересную информацию. Как бы-
ло отмечено при описании командного файла activ в предыдущей главе,
дата модификации представляет собой последний момент времени, когда
пользователь что-то набирал на своей клавиатуре. Другие даты тоже
кое-что означают, но они не так часто используются.


    ОБРАБОТКА ТЕРМИНАЛОМ ВВОДИМОЙ ИНФОРМАЦИИ



Как уже обсуждалось ранее, по умолчанию драйвер терминала работа-
ет в каноническом режиме, т.е. в режиме построчной обработки. Когда вы
вводите символы, драйвер ожидает, пока вы нажмете возврат каретки,
после чего передает для обработки всю строку. Если вы работаете не в
каноническом режиме, то каждый символ передается для обработки не-
посредственно после ввода. Наглядным примером такого режима работы яв-
ляется редактор vi. Вы нажимаете по одной клавише для движения курсо-
ра, удаления символов и т.д., поэтому редактор vi, очевидно, должен
получать каждый символ сразу же, как только нажата клавиша.

Каким образом это делается в программе? Прием старый и часто
используется в UNIX, хотя и не очень хорошо описан в документации. Та-
кого рода информацию можно добыть путем просмотра большого количества
текстов программ. Необходимо отметить, что этот прием лучше всего ра-
ботает в программах на языке Си. Командные файлы, написанные на языке
shell, могут использовать для этой цели команду stty, но результат бу-
дет не один и тот же. Следующий фрагмент программы на языке Си отклю-
чает каноническую обработку, затем читает символы и выводит их на эк-
ран.

1 #include

3 struct termio tsav, tchg;

5 main (argc, argv)
6 {
7 int c;

9 if (ioctl (0, TCGETA, &tsav) == -1) {
10 perror("can't get original settings");
невозможно получить исходные установки
11 exit(1);
12 }

14 tchg = tsav;

16 tchg.c_lflag &= ~(ICANON | ECHO);
17 tchg.c_cc[VMIN] = 1;
18 tchg.c_cc[VTIME] = 0;

20 if (ioctl (0, TCSETA, &tchg) == -1) {
21 perror("can't initiate new settings");
невозможно задать новые установки
22 }

24 while (1)
25 {
26 c = getchar();

28 if (c == 'x')
29 break;

31 putchar(c);
32 }

34 if (ioctl(0, TCSETA, &tsav) == -1) {
35 perror("can't reset original settings");
невозможно вернуть исходные установки
36 exit(3);
37 }
38 }

У нас есть две "терминальные" структуры данных, одна из которых
содержит исходные установки, а другая - установки, которые мы изменяем
и записываем. Первый системный вызов ioctl получает информацию об
установках терминала. Затем мы присваиваем эти значения изменяемой
структуре (строка 14). Модификации терминального интерфейса мы выпол-
няем в строках 16-18. Строка 16 отключает каноническую обработку и
эхо-отображение символов. Строка 17 устанавливает, что минимальное ко-
личество нажатий на клавиши равно одному. Строка 18 определяет, что
время ожидания для повторного чтения данных равно 0. По существу, это
блочное чтение по одному символу.

Новые значения терминальных характеристик устанавливаются в стро-
ке 20. В этот момент режим работы терминала меняется. Цикл while чита-
ет, проверяет и выводит символы. Только при вводе символа x цикл за-
вершается, терминал устанавливается в первоначальное состояние, и
программа заканчивает работу.

Как мы уже заметили, операция чтения здесь является блочной. Это
значит, что программа ожидает, пока вы введете символ. Если вы ничего
не вводите, программа находится в бесконечном цикле ожидания. Каким
образом мы изменяем режим чтения с блочного на посимвольный?

Этот вопрос эквивалентен такому вопросу: "Как опросить клавиатуру
в UNIX?". Опрос является весьма важным приемом для некоторых примене-
ний. Опрос работает примерно так: "Посмотреть на клавиатуру. Если вве-
ден символ, получить его и каким-то образом обработать. В противном
случае продолжать делать то, что вы делали. После истечения интервала
времени, определенного программой, проверить клавиатуру снова." Таким
образом, если пользователь не нажимает на клавиши, программа продолжа-
ет работу, а не ожидает, пока что-нибудь будет нажато на клавиатуре.

Для выполнения такой работы нам нужно несколько более подробно
рассмотреть терминальный интерфейс. Как было отмечено ранее, терминал
представляет собой файл. Это значит, что он должен обладать всеми
обычными свойствами файлов - возможностью открытия, закрытия, чтения,
записи и т.д. Мы также видели, что терминалы имеют протокол работы,
который может быть изменен командой stty. Мы видели, что для получения
одного символа с клавиатуры используется протокол работы. Теперь мы
увидим, что для выполнения опроса вы должны использовать технику, ко-
торая относится к файлам, а не ioctl.

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

1 #include
2 #include

4 struct termio tsav, tchg;

6 main (argc, argv)
7 {
8 int c;

10 /* change the terminal based on file primitives */
изменить режим терминала с помощью файловых примитивов
11 close(0);
12 if (open("/dev/tty",O_RDWR|O_NDELAY) == -1) {
13 perror("can't open tty");
невозможно открыть tty
14 exit(1);
15 }

17 /* change the terminal based on line disciplines */
изменить режим терминала с помощью протокола работы
18 if (ioctl (0, TCGETA, &tsav) == -1) {
19 perror("can't get original settings");
невозможно получить исходные установки
20 exit(2);
21 }

23 tchg = tsav;

25 tchg.c_lflag &= ~(ICANON | ECHO);
26 tchg.c_cc[VMIN] = 1;
27 tchg.c_cc[VTIME] = 0;

29 if (ioctl (0, TCSETA, &tchg) == -1) {
30 perror(can't initiate new settings");
невозможно задать новые установки
31 }

33 while (1)
34 {
35 putchar('.');
36 c = getchar();

38 if (c == 'x')
39 break;

41 putchar(c);
42 }

44 if (ioctl(0, TCSETA, &tsav) == -1) {
45 perror("can't reset original settings");
невозможно вернуть исходные установки
46 exit(3);
47 }
48 }

Основное изменение производится в строках 11-15. Закрытие файла с
нулевым дескриптором (который обозначает стандартное устройство ввода)
закрывает стандартный ввод. Затем мы снова открываем файл /dev/tty.
Значение дескриптора файла равно нулю, так что мы переназначили стан-
дартный ввод на новое устройство. Фокус в том, что при открытии файла
используется режим, называемый NODELAY. Это означает, что когда выпол-
няется чтение по данному дескриптору файла (т.е. чтение стандартного
ввода), вместо ожидания ввода выполняется просмотр, есть ли там
что-нибудь, а затем работа продолжается.

В бесконечном цикле строка 35 печатает точку. Когда вы запускаете
эту программу, на экран выводится точка, как только программа попадает
в цикл. Если вы ждете, то продолжают выводиться точки. Как только вы
нажмете клавишу, выполнится эхо-отображение символа в промежутке между
выводом точек. Это демонстрирует, что программа работает в то время,
когда вы ничего не делаете.


    ВОЗМОЖНОСТИ ТЕРМИНАЛОВ



Теперь, когда мы имеем понятие о характеристиках терминальных ин-
терфейсов, давайте перейдем к возможностям терминалов. ВОЗМОЖНОСТИ -
это те функции, которые выполняет аппаратура терминала. Если мы знаем
эту информацию, мы можем создать список возможных функций и использо-
вать его, например, для работы редактора vi. Это осуществляется при
помощи специального файла данных termcap (terminal capabilities - воз-
можности терминала), который описывает возможности терминала.

Большинство из существующих типов терминалов уже занесены в файл
termcap. Это файл /etc/termcap. Файл termcap и редактор vi происходят
из системы Berkeley. Такая комбинация оказалась настолько эффективной,
что была перенесена в System V. В более поздней System V Release 3
файл termcap уже не используется, его заменяет файл terminfo фирмы
AT&T. Мы применяли файл terminfo совместно с командным файлом today в
главе 5, но подробное обсуждение terminfo выходит за пределы нашей
книги. В системе Berkeley файл termcap по-прежнему остается стандар-
том, и он заслуживает более детального рассмотрения.

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

В качестве примера мы приводим запись файла termcap для компьюте-
ра Apple II. Это описание распространено в различных формах, но наш
пример относится к видеоплате Videx UltraTerm для Apple II+. Заметим,
что возможности, предоставляемые файлом termcap, являются обычно подм-
ножеством тех возможностей, которые фактически предоставляет аппарату-
ра. В частности, видеоплата в компьютере Apple выполняет некоторые
функции, которые не умеет делать файл termcap, например комбинации
настроечных битов для изменения видеоатрибутов. Самое большее, что мы
можем сделать с видеоатрибутами посредством файла termcap, это вклю-
чить или выключить инверсное отображение.

С другой стороны, некоторые типы аппаратуры не обладают всеми
возможностями, обеспечиваемыми файлом termcap. Например, одной из
функций, которой недостает в Apple, является функция прокрутки
("scroll reverse"). Аппаратура не делает этого, поэтому и в termcap
нет необходимости иметь описание этой функции. Вместо скроллинга
(прокрутки) вниз, отображаемый на экране текст продолжает выводиться в
верхней строке.

Для того, чтобы получить представление о том, как termcap соот-
носит общие характеристики терминала с конкретными возможностями,
сравним терминалы Apple и vt52. Две соответствующие записи в termcap
имеют много похожих функций, но совершенно разные коды для их выполне-
ния. Приведем пример содержимого файла termcap:

a2|aii|Apple II with UltraTerm :\
:bl=^G:\
:bs:\
:cd=^K:\
:ce=^]:\
:cl=^L:\
:cm=^^%r%+ %+ :\
:co#80:\
:cr=^M:\
:do=^J:\
:ho=^Y:\
:kb=^H:\
:kd=^J:\
:kl=^H:\
:kr=^\\:\
:ku=^_:\
:le=^H:\
:li#24:\
:nd=^\\:\
:nl=^J:\
:se=^O:\
:so=^N:\
:up=^_:

В табл. 7-1 представлен список функций файла termcap с сопостав-
лением терминалов Apple и vt52. Если какая-либо функция отсутствует у
одного или другого терминала, это отмечается словом "нет".


Таблица 7-1

Терминальные возможности и их конкретные значения

-------------------------------------------------------------
Функция Apple II vt52
-------------------------------------------------------------
bl - звуковой сигнал ^G ^G
(bell)
bs - возврат на шаг по коду ^H да да
(can backspace with ^H)
cd - очистка до конца экрана ^K \EJ
(clear to end of display)
ce - очистка до конца строки ^] \EK
(clear to end of line)
cl - очистка всего экрана ^L \EH\EJ
(clear entire screen)
cm - движение курсора ^^%r%+ %+ \EY%+ %+
(cursor motion)
co - число позиций в строке #80 #80
(number of columns in a line)
cr - возврат каретки ^M ^M
(carriage return)
do - сдвиг на строку вниз ^J ^J
(down one line)
ho - курсор в начало экрана
(без команды cm) ^Y \EH
(home cursor)
kb - код клавиши backspace ^H ^H
(sent by backspace key)
kd - код клавиши "стрелка вниз" ^J \EB
(sent by down arrow key)
kl - код клавиши "стрелка влево" ^H \ED
(sent by left arrow key)
kr - код клавиши "стрелка вправо" ^\\ \EC
(sent by right arrow key)
ku - код клавиши "стрелка вверх" ^_ \EA
(sent by up arrow key)
le - курсор влево ^H ^H
(cursor left)
li - число строк экрана #24 #24
(number of lines per screen)
nd - нестирающий пробел ^\\ \EC
(nondestructive space)
nl - символ перевода строки ^J ^J
(newline character)
pt - наличие аппаратной табуляции нет да
(has hardware tabs)
se - обычный экран ^O нет
(end stand out mode (normal))
so - инверсный экран ^N нет
(begin stand out mode (inverse))
sr - прокрутка нет \EI
(scroll reverse)
ta - символ табуляции ^I ^I
(tab)
up - сдвиг вверх на строку нет ^_
(up a line)
-------------------------------------------------------------

Самое интересное здесь, наверное, то, что терминалы vt52 и Apple
имеют взаимно обратный порядок указания координат в команде движения
курсора. Терминал vt52 воспринимает значения x и y в порядке YX, что
является умолчанием для файла termcap. Apple воспринимает их в порядке
XY, поэтому в записи файла termcap требуется поменять координаты
местами, что указано обозначением %r в функции cm.

Файл termcap позволяет вам спрятать основную информацию о специ-
фических характеристиках терминала (за исключением характеристик, ко-
торые могут отсутствовать у терминала, или специальных возможностей,
которые не описаны в termcap). Это значит, что вы можете создавать
терминально-независимые программы. При этом вам нет необходимости из-
менять все специфические обращения к терминалу, такие как ESC-последо-
вательности (символы, указывающие терминалу, что передаваемые после
них символы (символ) должны интерпретироваться как управляющие коды).
Это символы (\E) для терминала vt52 и (^) для Apple.

Наилучший пример - способ использования файла termcap редактором
vi. Он начинает выполнять указанную ему функцию, например движение
курсора, после чего ставит вопрос: "Какой код функции, которую мы хо-
тим выполнить?". Затем он ищет соответствующую последовательность в
той информации, которую предоставляет termcap.

С другой стороны, иногда вам необходимо оптимизировать какую-либо
функцию по скорости, заставив ее посылать коды непосредственно на оп-
ределенный терминал. В этом случае вам опять-таки полезен файл
termcap, поскольку вы можете найти необходимую информацию в соот-
ветствующем файле termcap, после чего закодировать эту информацию в
вашей программе. Это мы и делаем в первой инструментальной программе
данной главы - программе 'c'.

--------------------------------------------------------
ИМЯ: c
--------------------------------------------------------

c Быстрая очистка экрана


    НАЗНАЧЕНИЕ



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


    ФОРМАТ ВЫЗОВА



c

    ПРИМЕР ВЫЗОВА



c Очистка экрана


    ТЕКСТ ПРОГРАММЫ



1 char id[] = "@(#) c v1.0 Fast clear screen Author: Russ Sage";
Быстрая очистка экрана

3 #define FF "\014"

5 main()
6 {
7 if (write(1, FF, 1) == -1)
8 write(2,"c: write error to stdout\n",25);
ошибка записи в стандартный вывод
9 }


ОПИСАНИЕ

ЗАЧЕМ НАМ НУЖНА ПРОГРАММА c?

В System V уже имеется команда для очистки экрана терминала - это
команда clear. Она работает путем определения типа вашего терминала и
затем вывода на экран символа очистки для данного терминала. Все прек-
расно, но есть один существенный недостаток: она очень МЕДЛЕННАЯ!

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


ЧТО ДЕЛАЕТ c?

Программа 'c' выводит на экран символ очистки настолько быстро,
насколько быстро может выполняться операция ввода-вывода в UNIX. При-
меняя прямой системный вызов, мы избавляемся от необходимости за-
пускать другую программу. Поэтому программа 'c' работает очень быстро.
Мы уверены, что точно такую же функцию можно вызывать как команду
Си-shell (поместить в csh alias), поэтому данная программа наиболее
полезна тем, кто работает в System V.

Для того чтобы определить, какой символ очистки соответствует ва-
шему терминалу, найдите строку с обозначением cl в файле termcap. Это
и есть то значение, которое вы должны вручную вставить в данную прог-
рамму. Если вы работаете не на таком терминале, для которого эта прог-
рамма написана, то данная команда будет работать неверно.


    ПОЯСНЕНИЯ



Первым делом мы должны найти в файле termcap код очистки экрана.
Для терминала Apple это код ^L, а для vt52 это \EH\EJ. Как только вы
найдете этот код, вставьте его в оператор define в строке 3 или сразу
в оператор write в строке 7. В приведенном примере в качестве символа
очистки экрана используется ^L.

Наиболее быстрым способом передачи символа в файл является не-
посредственное выполнение оператора write. Поскольку терминалы явля-
ются файлами, мы можем выполнять запись непосредственно в них, пользу-
ясь преимуществом предопределенных дескрипторов файла 0,1 и 2.

Системный вызов write в строке 7 посылает символ очистки в файл с
дескриптором 1, который является стандартным устройством вывода. Если
операция записи неудачна (по ряду причин), то в файл с дескриптором 2,
т.е. на стандартное устройство регистрации ошибок, выводится сообщение
об ошибке. Здесь не проверяется, успешно ли завершилась запись на
стандартное устройство регистрации ошибок. Если ошибка все-таки воз-
никнет, то мы ее увидим.

Программа не использует НИКАКИХ возможностей стандартного вво-
да-вывода (stdio). НИКОГДА нельзя смешивать системные вызовы ввода-вы-
вода (т.е. вызовы из раздела (2) документации по системным функциям,
например read или write) со стандартными вызовами ввода-вывода (т.е.
вызовами из раздела (3), такими как getchar и printf). Дополнительный
буфер, который создается при выполнении функций stdio, не согласован
во времени с системными вызовами, поэтому все выходные сообщения пере-
мешиваются.

Еще один аспект, о котором мы должны помнить, принимая решение об
использовании системных вызовов, это преимущество получения как можно
более короткого объектного кода. Небольшая программа загружается и ра-
ботает быстрее. Для того, чтобы ненужные подпрограммы стандартного
ввода-вывода не включались в наш объектный модуль, в исходном тексте
программы не делается никаких ссылок на подпрограммы stdio. Тем не ме-
нее, ваша система могла их каким-то образом включить. Так поступает
XENIX, а вместе с stdio вызывается malloc и все остальное. Вы можете
просмотреть таблицу символов вашего объектного модуля с помощью nm(1)
или nlist(2). Вы увидите весь мусор, который был добавлен в ваш объек-
тный модуль. Не так редко мы получаем 6 Кб кода всего лишь для одного
оператора printf! Приучайтесь программировать непосредственно на
ассемблере, чтобы достичь того, что вам нужно.


    ИССЛЕДОВАНИЯ



Когда эта программа была написана, возник вопрос: "Каким образом
мы можем проверить неудачу записи на стандартное устройство вывода?".
Раньше такой вопрос не стоял, но показалось, что неплохо было бы это
сделать. Решение было найдено на страницах описания sh(1). Способ, ко-
торым можно вызвать ошибку выполнения записи на стандартное устройство
вывода, заключается в том, что нужно закрыть дескриптор файла стан-
дартного устройства вывода. Это легко делается с помощью команды exec,
которая является внутренней по отношению к shell:

$ exec >&-

Эта команда переназначает файловый дескриптор 1 стандартного вы-
вода (обозначение >) на дескриптор файла (&) закрытого устройства (-).
Такой эксперимент может оказаться полезным для более полной отладки
ваших программ.


    ДИСКОВЫЕ УСТРОЙСТВА



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

Основное отличие между дисками и терминалами заключается в том,
что диски являются блочными устройствами, а терминалы - символьными.
Вместо того, чтобы выполнять обмен информацией по одному символу,
диски обмениваются блоками по 512 или 1024 символа. Имеются команды,
которые управляют разбиением на блоки и буферизацией, что делает воз-
можным выполнение блочных операций ввода-вывода.


    РАЗБИЕНИЕ ДИСКОВ НА РАЗДЕЛЫ



Части, или области диска, известны как разделы. Раздел может со-
держать файловую систему, которая сгенерирована командой mkfs(1), или
же может содержать неструктурированные данные, доступ к которым выпол-
няется с помощью команды 'cpio -o'.

В системе XENIX управление разделами осуществляется программой
fdisk, которая концептуально подобна своей тезке в системе MS-DOS. В
других системах UNIX используются другие имена. Например, в системе
AT&T 7300 UNIX PC используется программа iv, что значит "format" (хо-
тите верьте, хотите нет). Как упоминалось ранее, обычно разделы содер-
жат одну файловую систему. В настоящее время в системах XENIX и SCO
XENIX у вас есть возможность "разделить раздел" на более мелкие части
для получения большего количества файловых систем. Это сделано по той
причине, что машины с системами DOS и XENIX ограничены четырьмя диско-
выми разделами, а у вас может возникнуть желание иметь больше файловых
систем, чем число доступных разделов. В системе AT&T 7300 UNIX PC уп-
равление разделами диска осуществляется по списку начальных номеров
дорожек. Вы можете создать столько разделов, сколько хотите. Каждый
компьютер имеет свои преимущества и недостатки.

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

-------------------------
|
| brw------- 1 sysinfo sysinfo 1, 0 Feb 18 17:07 /dev/hd00
| brw------- 1 sysinfo sysinfo 1, 15 Feb 18 16:59 /dev/hd01
| brw------- 1 sysinfo sysinfo 1, 23 Feb 18 16:59 /dev/hd02
| brw------- 1 sysinfo sysinfo 1, 31 Feb 18 16:59 /dev/hd03
| brw------- 1 sysinfo sysinfo 1, 39 Feb 18 16:59 /dev/hd04
| brw------- 1 sysinfo sysinfo 1, 47 Feb 18 17:07 /dev/hd0a
| brw------- 1 sysinfo sysinfo 1, 55 Feb 18 17:09 /dev/hd0d
| crw------- 1 sysinfo sysinfo 1, 0 Feb 18 16:59 /dev/rhd00
| crw------- 1 sysinfo sysinfo 1, 15 Feb 18 16:59 /dev/rhd01
| crw------- 1 sysinfo sysinfo 1, 23 Feb 18 16:59 /dev/rhd02
| crw------- 1 sysinfo sysinfo 1, 31 Feb 18 16:59 /dev/rhd03
| crw------- 1 sysinfo sysinfo 1, 39 Feb 18 16:59 /dev/rhd04
| crw------- 1 sysinfo sysinfo 1, 47 Feb 18 16:59 /dev/rhd0a
| crw------- 1 sysinfo sysinfo 1, 55 Feb 18 17:09 /dev/rhd0d
|

Имена файлов с префиксом hd указывают блочные устройства, а с
префиксом rhd - "неструктурированные" символьные устройства. Не все
символьные устройства являются неструктурированными блочными уст-
ройствами. Терминалы являются символьными устройствами, как мы уже ви-
дели ранее в данной главе. В табл. 7-2 показаны различные характе-
ристики этих двух типов устройств.


Таблица 7-2

Сравнение блочных и символьных устройств

-------------------------------------------------------------
Блочное устройство Символьное устройство
-------------------------------------------------------------

/dev/hd0, /dev/fd0 /dev/rhd0, /dev/rfd0

буфер управляется ядром буферизация отсутствует,
системы, медленное устройство быстрое устройство

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

доступ через файловую доступ непосредственно
систему на диск

cpio -p cpio -o, -i

mkfs, mount, df, du tar
fsck, fsdb

------------------------------------------------------------

Как видите, существует много способов работы с устройствами.

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

# mkfs /dev/hd01 5000

Внутри раздела (размером не менее 5000 Кб) размещается файловая
система. Файловая система содержит суперблок, списки свободных блоков
и т.п., то есть все, что необходимо для хранения файлов, которые раз-
мещаются здесь. Однако, создание файловой системы совсем НЕ означает,
что вы сразу же можете получить к ней доступ. Сначала вам необходимо
смонтировать файловую систему. Команда для выполнения этой операции
может иметь такой вид:

# mount /dev/hd01 /mount_pt

Файлы могут быть помещены в дисковый раздел командами mv или cp,
путем переадресации вывода в каталог с этим именем, например,
>/mount_pt/file.

Для использования раздела диска в качестве области неструктуриро-
ванных данных, а не блочного устройства, применяйте файл с именем сим-
вольного устройства, которое начинается с буквы r. Например, для
использования того же устройства, что и в предыдущем примере, в ка-
честве неструктурированного устройства, укажите имя /dev/rhd01. (Из
списка устройств вы видите, что это символьное устройство, так как
права доступа в первой колонке начинаются с символов crw, а не brw).
Это устройство (и соответствующий раздел) в данный момент не имеет
файловой системы и является просто набором байтов. Единственным огра-
ничением является то, что вы можете записать в этот раздел не более 5
Мб данных.

Вот пример команды, использующей неструктурированное устройство:

$ find . -print | cpio -ocBv > /dev/rhd01


    ИЗУЧЕНИЕ ДАННЫХ



Когда данные находятся на диске, их можно изучить более тщатель-
но, чем с помощью команд cat, more и других. Делается это командой
od(1), которая выдает дамп файла устройства, как показано в следующем
примере:

$ od -c /dev/hd01

Если бы вы получали дамп файла НЕСТРУКТУРИРОВАННОГО устройства
(/dev/rhd01), то это выглядело бы точно так же. Единственное отличие
заключается в том, как драйвер осуществляет доступ к данным. Формат, в
котором будут выводиться данные, зависит от того, какой командой про-
изводилось копирование: cpio, tar, mkfs или какой-то иной. Некоторые