Главная » Программирование для UNIX » Устройства UNIX

0

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

обзор всех существующих файлов. Как  видно  из названия, /dev содержит файлы устройств.

Одна  из  самых удачных идей  в системе UNIX заключается в способе работы с периферийными устройствами – дисками, магнитными лентами, принтерами, терминалами и т. п.  Вместо того  чтобы  использовать  специальные подпрограммы для работы, например, с магнитными лентами, система обращается к файлу /dev/mt0 (как всегда, имя  может отличаться). Внутри ядра обращения к этому файлу транслируются  в  команды  работы с  лентой,  поэтому программа,  выполняющая чтение /dev/mt0, получает данные со смонтированной в данный момент ленты. Например, команда

$ cp /dev/mt0 junk

копирует содержимое ленты в файл с именем junk. Команду cp не инте ресуют  особенности файла /dev/mt0, для  нее это просто последовательность байтов.

Файлы устройств – как обитатели зоопарка, каждый имеет  свои  особенности, но основные  идеи  файловой системы применимы ко всем. Вот небольшой фрагмент каталога /dev:

$ ls -l /dev

crw––w––w–  1 root           0,    0 Sep 27 23:09  console crw–r––r––  1 root           3,    1 Sep 27 14:37  kmem crw–r––r––  1 root           3,    0 May    6   1981 mem brw–rw–rw–  1 root           1,  64 Aug  24 17:41  mt0 crw–rw–rw–  1 root           3,    2 Sep 28 02:03  null crw–rw–rw–  1 root           4,  64 Sep   9 15:42  rmt0

brw–r––––– 1 root

2,

0 Sep   8  08:07  rp00

brw–r––––– 1 root

2,

1 Sep 27  23:09  rp01

crw–r––––– 1 root

13,

0 Apr  12    1983  rrp00

crw–r––––– 1 root

13,

1 Jul  28  15:18  rrp01

crw–rw–rw–  1 root

2,

0 Jul    5  08:04  tty

crw––w––w–  1 you

1,

0 Sep 28  02:38  tty0

crw––w––w–  1 root

1,

1 Sep 27  23:09  tty1

crw––w––w–  1 root

1,

2 Sep 27  17:33  tty2

crw––w––w–  1 root

1,

3 Sep 27  18:48  tty3

$

В первую очередь следует обратить внимание на то, что вместо  длины файла присутствуют два целых числа, а первый символ в строке прав доступа всегда  b или  c. Таким способом  команда ls показывает, что запись  индексного дескриптора относится к устройству, а не к обычному файлу. Индексный дескриптор обычного файла содержит список дисковых блоков, в которых хранится содержимое файла. В индексном дескрипторе файла устройства  содержится внутреннее имя устройства, состоящее из  обозначения типа  символа c для  символьного или  b для  блочного,  и пара  чисел,  называемых старшим и младшим номерами устройства. Диски и ленты являются блочными устройствами, а все ос-

тальные – терминалы, принтеры, телефонные линии и т. д. – символьными. Старший номер определяет тип  устройства, а младший обозначает  конкретный экземпляр устройства.  Например, /dev/tty0 и /dev/ tty1 – это два порта контроллера терминала и поэтому они имеют одинаковые старшие номера и разные младшие номера.

Файлы дисков обычно  получают имена в соответствии с маркой устройства. Так, файлы устройств для  диска DEC RP06 называются /dev/ rp00 и /dev/rp01. В действительности это одно физическое устройство, логически разделенное на две файловые системы. Если  в системе при сутствует второй жесткий  диск,  то  его  файлы устройства получают имена /dev/rp10 и /dev/rp11. Первая цифра обозначает номер  физического диска, а вторая – номер логического раздела.

Может возникнуть вопрос, почему используется не один  файл дискового устройства, а несколько. Исторически сложилось так, что файловая система состоит из отдельных подсистем, кроме того, это облегчает ее сопровождение. Доступ  к файлам подсистемы осуществляется через  каталоги  основной системы. Программа /etc/mount  показывает соответствие файлов устройств и каталогов:

$ /etc/mount

rp01  on /usr

$

В данном случае корневая система размещается на устройстве /dev/rp00 (хотя /etc/mount  об этом  не  сообщает),  а  пользовательская файловая система – файлы каталога /usr и его подкаталоги – на устройстве /dev/ rp01.

Корневая  файловая  система необходима для  работы операционной системы. Каталоги /bin, /dev и /etc всегда  находятся в корневой файловой  системе, так как это единственная файловая система, доступная при  загрузке, и в ней хранятся файлы, участвующие в запуске опера ционной системы, такие как /bin/sh.  В процессе начальной загрузки проверяется  целостность  всех   файловых  систем (см.  icheck(8)  или  fsck(8)), после  чего  они присоединяются к корневой системе. Операция присоединения называется монтированием и представляет собой программный аналог  установки нового  диска в дисковод, для ее выполнения необходимы привилегии суперпользователя. После  того как устройство  /dev/rp01 смонтировано в  каталог /usr, файлы  пользовательской файловой системы доступны так  же, как если  бы они входили в корневую файловую систему.

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

грамму,  находящуюся  в  /bin, так   как эти  каталоги  принадлежат разным файловым системам:

$ ln  /bin/mail /usr/you/bin/m

ln: Cross–device   link

$

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

Во-вторых, файловые системы имеют  ограничения на  размер (количество  блоков, доступных для  размещения файлов) и количество индексных дескрипторов. Если  подсистема заполнена,  то  невозможно увеличить файл, не освободив предварительно дисковое пространство. Команда df (disc free space  – свободное дисковое пространство) показывает  количество свободного места  в смонтированных файловых систе мах:

$ df

/dev/rp00 1989

/dev/rp01 21257

$

Здесь  /usr содержит 21 257 свободных блоков. Много это или  мало, зависит от  того,  как  используется система, требования к  свободному пространству могут  очень  сильно отличаться. Между прочим, из всех команд df, возможно, имеет  наибольшее разнообразие выходных форматов. В других системах результат ее выполнения может выглядеть совершенно по-другому.

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

Команда tty выводит данные о терминале пользователя:

$ who  am  i

you           tty0        Sep 28 01:02

$ tty

/dev/tty0

$ ls -l /dev/tty0

crw––w––w–  1 you            1,  12 Sep 28 02:40  /dev/tty0

$ date >/dev/tty0

Wed  Sep 28 02:40:51  EDT  1983

$

Обратите внимание,  что  устройство  принадлежит вам, и  только вы имеете разрешение на его чтение. Другими словами, никто не может следить непосредственно за тем, что  вводится с клавиатуры. В то же время, вывод  на  терминал пользователя доступен всем. Этого можно избежать, изменив командой chmod права доступа к устройству, – тогда

другие пользователи не смогут послать вам сообщение командой write.

Также для этой цели можно выполнить команду mesg.

$ mesg  n                        Выключить вывод  сообщений

$ ls -l /dev/tty0

crw––––––– 1 you            1,  12 Sep 28 02:41  /dev/tty0

$ mesg  y                        Восстановить

$

Часто возникает  необходимость обратиться к  своему   терминалу по имени. Чтобы не заниматься его поисками, можно использовать устройство /dev/tty,  которое является  синонимом текущего терминала, независимо от его настоящего имени.

$ date >/dev/tty

Wed  Sep 28 02:42:23  EDT  1983

$

Особенно удобно устройство /dev/tty для организации взаимодействия с пользователем, когда стандартный ввод  и вывод перенаправлены в файлы. Одной  из  программ,  использующих /dev/tty,  является crypt. Открытый текст считывается из стандартного ввода, зашифрованные данные выводятся  в  стандартный  вывод, а  ключ для шифрования crypt получает из /dev/tty:

$ crypt <cleartext  >cryptedtext

Enter  key:                                          Введите ключ для шифрования

$

Здесь  нет  явного упоминания устройства  /dev/tty, но,  тем  не  менее, оно используется. Ключ не может быть получен из стандартного ввода, поскольку тот предназначен для чтения исходного файла. Поэтому команда crypt открывает файл /dev/tty и считывает оттуда ключ, отключив автоматический эхо-вывод, поэтому ваш шифрующий ключ не появляется на экране. В главах 5 и 6 будут  рассмотрены еще несколько применений /dev/tty.

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

Вывод команды news можно исключить, перенаправив его в устройство

/dev/null:

$ news >/dev/null

$

Данные, выводимые в /dev/null, пропадают без каких-либо комментариев, а при попытке ввода из /dev/null программа немедленно получает  признак конца файла, так  как  операция чтения возвращает ноль  байт.

Часто /dev/null служит для того, чтобы выделить из выходных данных программы диагностические сообщения. Например, команда time (ti– me(1)) показывает использование процессора программой. Эта информация направляется в стандартный вывод ошибок, что позволяет хронометрировать программы с большим объемом вывода, направляя его в /dev/null:

$ ls -l /usr/dict/words

–r––r––r––  1 bin        196513 Jan  20   1979  /usr/dict/words

$ time  grep  e /usr/dict/words  >/dev/null

real

13.0

user

9.0

sys

2.7

$ time  egrep  e /usr/dict/words >/dev/null

real

8.0

user

3.9

sys

2.8

$

Значения, выводимые командой time, показывают общее время выполнения, процессорное время, затраченное программой, и процессорное время, затраченное ядром. Команда egrep  – это более быстрый вариант grep, который будет  рассмотрен в главе 4; при  поиске в больших фай лах  egrep работает примерно вдвое быстрее. Если  вывод  grep и egrep не перенаправить в файл или  в /dev/null, то придется ждать окончания вывода на  терминал  сотен  тысяч символов, чтобы  получить  нужную информацию.

Упражнение 2.9.  Изучите остальные файлы каталога /dev в разделе 4 руководства. В чем разница между /dev/mt0 и /dev/rmt0? Объясните возможные преимущества использования подкаталогов в /dev для дисков, лент и т. п. ~

Упражнение 2.10.  Ленты, записанные в системах, отличных от UNIX, часто  имеют разные размеры блоков, например 800  байт – для десяти 80-символьных перфокарт, но ленточное устройство /dev/mt0 рассчитано на блоки длиной 512  байт. Изучите команду dd  (dd(1)), используемую при чтении таких лент. ~

Упражнение 2.11.  Почему устройство /dev/tty не реализовано как ссыл ка  на  терминал,  с которого выполнялась регистрация? Что произойдет,  если  установить ему права доступа rw––w––w–, как у текущего терминала? ~

Упражнение 2.12.  Как  работает write(1)? Подсказка: см. utmp(5). ~

Упражнение 2.13.  Как  определить, что пользователь недавно работал с терминалом? ~

История и библиография

Файловой системе посвящена одна из частей исследования «UNIX implementation» (Реализация UNIX) Кена  Томпсона (Ken Thompson), изданного в BSTJ  (Bell System Technical Journal) в июле  1978  года. Док лад Денниса Ритчи (Dennis Ritchie) «The  evolution of the  UNIX  timesharing system» (Эволюция разделения времени в UNIX), сделанный на симпозиуме по разработке языков и методологии программирования (Symposium on Language Design and  Programming Methodology) в Сиднее  (Австралия) в  сентябре  1979   года,   представляет прекрасное описание того,  как была  спроектирована и реализована файловая система  в первой ОС UNIX на PDP-7 и как она доросла до сегодняшнего состояния.

Файловая система UNIX  вобрала в себя  некоторые идеи  из  системы MULTICS. Эта  система всесторонне рассмотрена в  труде  «The  MULTICS System: An Examination of its Structure» (Система MULTICS: Исследование структуры) Органика (E. I. Organick), изданном MIT Press в 1972  году.

В статье «Password security: a case history» (Безопасность паролей: наглядная  иллюстрация) Боба  Морриса (Bob  Morris) и  Кена  Томпсона приведено занимательное сравнение механизмов паролей на ряде  систем; о нем  рассказано во втором томе  руководства по UNIX  для программиста).

Помещенная в том же  томе  статья Денниса Ритчи «On the  security of UNIX» (О безопасности в UNIX) объясняет, почему безопасность системы  больше зависит от  грамотного администрирования,  чем  от  использования программ типа  crypt.

Источник: Керниган Б., Пайк Р., UNIX. Программное окружение. – Пер. с англ. – СПб: Символ-Плюс, 2003. – 416 с., ил.

По теме:

  • Комментарии