Текст книги "UNIX — универсальная среда программирования"
Автор книги: Брайан Керниган
Соавторы: Роб Пайк
сообщить о нарушении
Текущая страница: 6 (всего у книги 31 страниц) [доступный отрывок для чтения: 12 страниц]
2.5 Индексные дескрипторы
Файл имеет несколько атрибутов: имя, содержимое и служебную информацию (права доступа и даты модификации). Служебная информация размещается в индексном дескрипторе вместе с важной системной информацией, такой, как размер файла, место хранения его на диске и т.д.[8] 8
Индексный дескриптор обозначается как inode ("index node") или i-node. – Прим. перев.
[Закрыть] В индексном дескрипторе хранятся три даты: время последнего изменения файла (записи в него), время последнего использования файла (чтение или выполнение), время последнего изменения самого индексного дескриптора, например изменения прав доступа.
$ date
Tue Sep 27 12:07:24 EDT 1983 $ date > junk
$ ls -l junk
-rw-rw-rw 1 you 29 Sep 27 12:07 junk
$ ls -lu junk
-rw-rw-rw 1 you 29 Sep 27 06:11 junk
$ ls -lc junk
-rw-rw-rw 1 you 29 Sep 27 12:07 junk
$
Как видно из результата действия команды ls -lu
, изменение содержимого файла не влияет на дату последнего использования, а с изменением прав доступа связана только дата изменения индексного дескриптора, о чем выдается сообщение командой ls -lc
:
$ chmod 444 junk
$ ls -lu junk
-r–r–r– 1 you 29 Sep 27 06:11 junk
$ ls -lc junk
-r–r–r– 1 you 29 Sep 27 12:11 junk
$ chmod 666 junk $
Можно использовать флаг -t
команды ls
, который применяется для сортировки файлов по времени (по умолчанию принимается время последней модификации), совместно с флагами -с
или -r
, чтобы узнать порядок, в котором изменились индексные дескрипторы или читались файлы:
$ ls recipes
apple
pie
$ ls -lut total 2
drwxrwxrwx 4 you 64 Sep 27 12:11 recipes
-rw-rw-rw– 1 you 29 Sep 27 06:11 junk
У каталога recipes
, как вы видите, более позднее время использования, поскольку мы только что просмотрели его содержимое.
Очень важное понять значение индексного дескриптора, причем не для того, чтобы оценить действие флагов команды ls
. По существу, индексные дескрипторы и есть файлы. Иерархия каталогов предоставляет только удобный способ именования файлов. Внутреннее системное имя файла или индекс файла – это номер индексного дескриптора, содержащего информацию о файле. Команда ls -i
выдает индекс файла в десятичной форме:
$ date > x
$ ls -i
15768 junk
15274 recipes
15852 x
$
Именно индекс файла хранится в первых двух байтах каталога, предшествующих имени. Команда od -d
выдает информацию не в восьмеричной форме по байтам, а в десятичной, объединив по два байта в одно целое, и поэтому мы увидим на экране индекс файла:
$od -с .
0000000 4 ; .
0000020 273 ( . .
0000040 252 ; p е ц п т ы
0000060 230 = j u n к
0000100 354 = x
0000120
od -d .
0000000 15156 00046 00000 00000 00000 00000 00000 00000
0000020 10427 11822 00000 00000 00000 00000 00000 00000
0000040 15274 25970 26979 25968 00115 00000 00000 00000
0000060 15768 30058 27502 00000 00000 00000 00000 00000
0000100 15852 00120 00000 00000 00000 00000 00000 00000
0000120
$
Первые два байта в каждой строке каталога являются единственной связью между именем файла и его содержимым. Именно поэтому имя файла в каталоге называется связью: оно связывает имя в иерархии каталогов с индексным дескриптором и, тем самым, с информацией. Один и тот же индекс файла может появиться в нескольких каталогах. Команда rm
в действительности удаляет не индексный дескриптор, а строку каталога или связь. Только когда последняя связь файла исчезает, система удаляет индексный дескриптор, а значит, и сам файл.
Если индекс файла в строке каталога равен нулю, это означает, что связь удалена, но сам файл не обязательно удален – могут существовать связи где-нибудь еще. Можно убедиться в том, что индекс файла становится равным нулю при удалении файла:
$ rm x $ od -d .
0000000 15156 00046 00000 00000 00000 00000 00000 00000
0000020 10427 11822 00000 00000 00000 00000 00000 00000
0000040 15274 25970 26979 25968 00115 00000 00000 00000
0000060 15768 30058 27502 00000 00000 00000 00000 00000
0000100 00000 00120 00000 00000 00000 00000 00000 00000
0000120
$
Следующий файл, создаваемый в этом каталоге, займет освободившуюся позицию, хотя у него, вероятно, будет другой индекс. Команда ln
, имеющая приведенный ниже синтаксис, устанавливает связь с уже существующим файлом:
$ ln old-file new-file
Назначение связи состоит в том, чтобы дать два имени одному и тому же файлу, поэтому он часто оказывается в двух разных каталогах. Во многих системах есть связь с редактором /bin/ed
под названием /bin/е
, так что пользователи могут вызывать редактор как е
. Две связи одного файла указывают на одну и ту же запись, а значит, имеют один и тот же индекс файла:
$ ln junk linktojunk
$ ls -li total 3
15768 -rw-rw-rw– 2 you 29 Sep 27 12:07 junk
15768 -rw-rw-rw– 2 you 29 Sep 27 12:07 linktojunk
15274 drwxrwxrwx 4 you 64 Sep 27 09:34 recipes
$
Целое число, выдаваемое между правом доступа и именем владельца файла, является числом связей файла. Поскольку каждая связь ссылается на индексный дескриптор, все связи одинаково, важны – нет разницы между первой связью и последующими. (Заметим, что общий объем занимаемого на диске пространства, сообщаемый командой ls
, вычисляется неверно из-за двойного подсчета).
Если изменить файл, то изменение обнаружится при обращении к файлу под любым из его имен, так как все связи ссылаются на один файл:
$ echo x > junk
$ ls -l total 3
-rw-rw-rw– 2 you 2 Sep 27 12:37 junk
-rw-rw-rw– 2 you 2 Sep 27 12:37 linktojunk
drwxrwxrwx 4 you 64 Sep 27 09:34 recipes
$ rm linktojunk
$ ls -l total 2
-rw-rw-rw– 1 you 2 Sep 27 12:37 junk
drwxrwxrwx 4 you 64 Sep 27 09:34 recipes
$
После удаления файла linktojunk
число связей опять становится равным единице. Как уже отмечалось, при удалении файла уничтожается лишь связь. Сам же файл сохраняется до тех пор, пока не будет удалена последняя связь. На практике, конечно, большинство файлов имеет единственную связь, но тем не менее вы убедились в том, что можно простым способом повысить гибкость системы.
Предостережение тем, кто слишком торопится: после удаления последней связи данные становятся недоступными. Удаленные файлы попадают скорее в топку, чем в мусорную корзину, и нет средства возродить их из пепла. (Слабая надежда на возрождение все-таки есть. В больших системах UNIX есть рутинная функция дублирования, которая периодически копирует изменяемые файлы в какое-нибудь надежное место типа магнитной ленты, откуда их можно извлечь. Для собственного успокоения вам следует знать, какой объем дублирования обеспечивает ваша система. Если нет ничего, будьте бдительны – любые неполадки с дисками могут обернуться катастрофой.)
Связи файла удобны, если два пользователя совместно работают с ним, но иногда нужна на самом деле отдельная копия – другой файл с той же информацией. Например, вы можете скопировать документ до внесения в него существенных изменений, так что можно будет восстановить оригинал, если вас не устроят эти изменения. Здесь не поможет установление связи, так как при изменении данных обе связи будут ссылаться на измененный файл. Копирует файлы команда cp
:
$ cp junk copyofjunk
$ ls -li total 3
15850 -rw-rw-rw– 1 you 2 Sep 27 13:13 copyofjunk
15768 -rw-rw-rw– 1 you 2 Sep 27 12:37 junk
15274 drwxrwxrwx 4 you 64 Sep 27 09:34 recipes
$
Индексы файлов junk
и copyofjunk
различны, поскольку это различные файлы, хотя в данный момент они имеют одинаковое содержимое. Существует полезный прием: можно изменить права доступа к копии файла, чтобы ее труднее было случайно удалить.
$ chmod -w copyofjunk
Убрать право записи
$ ls -li total 3
15850 -r–r–r– 1 you 2 Sep 27 13:13 copyofjunk
15768 -rw-rw-rw– 1 you 2 Sep 27 12:37 junk
15274 drwxrwxrwx 4 you 64 Sep 27 09:34 recipes
$ rm copyofjunk
rm: copyofjunk 444 mode n
Нельзя! Он нужен
$ date > junk
$ ls -li total 3
15850 -r–r–r– 1 you 2 Sep 27 13:13 copyofjunk
15768 -rw-rw-rw– 1 you 29 Sep 27 13:16 junk
15274 drwxrwxrwx 4 you 64 Sep 27 09:34 recipes
$ rm copyofjunk
rm: copyofjunk 444 mode y
А может быть, и не так нужен
$ ls -li total 2
15768 -rw-rw-rw– 1 you 29 Sep 27 13:16 junk
15274 drwxrwxrwx 4 you 64 Sep 27 09:34 recipes
$
Изменение копии файла или ее удаление не оказывает действия на оригинал. Обратите внимание на то, что, поскольку у файла copyofjunk
отменено право на запись, команда rm запрашивает подтверждение, прежде чем удалить файл.
Есть еще одна команда общего назначения, управляющая файлами, – mv
, которая переносит или переименовывает файлы, просто преобразуя связи. Синтаксис ее такой же, как у команд cp
и ln
:
$ mv junk sameoldjunk $ ls -li total 2
15274 drwxrwxrwx 4 you 64 Sep 27 09:34 recipes
15768 -rw-rw-rw– 1 you 29 Sep 27 13:16 sameoldjunk
$
sameoldjunk
– это тот же самый файл, что и наш старый файл junk
, вплоть до индекса файла, который связан с записью каталога с номером 15768; изменилось только его имя.
Все описанные выше манипуляции с файлами происходили в одном каталоге, однако команды применяются и в других каталогах. Команда ln
часто используется для того, чтобы установить связь с одним именем в разных каталогах; это бывает в тех случаях, когда несколько пользователей работают с одной программой или над одним документом. Команда mv может переслать файл или каталог из одного каталога в другой. На самом деле, это довольно стандартный прием, так что у команд mv
и cp
есть специальный синтаксис для такой ситуации:
$ mv
(или cp
) file1 file2 ... directory
Здесь показана пересылка (или копирование) одного или нескольких файлов в каталог, который является последним аргументом. Связи или копии файлов получаются под теми же именами. Например, если вы хотите "набить руку" в работе с редактором, то можете начать с
$ cp /usr/src/cmd/ed.с .
получив свою копию исходного текста редактора для экспериментов. Осваивая интерпретатор shell
, исходные тексты которого находятся в нескольких каталогах, задайте
$ mkdir sh
$ cp /usr/src/cmd/sh/* sh
и команда cp
скопирует все исходные тексты shell
в ваш вложенный каталог sh
(мы считаем, что в /usr/src/cmd/sh
нет вложенных каталогов, так как команда cp
не слишком "умна"). В некоторых случаях команду ln
допустимо применять с несколькими именами файлов в качестве аргументов, но имя каталога по-прежнему является последним аргументом. В ряде систем команды mv
, cp
и ln
сами служат связями, ссылающимися на один файл, который анализирует имя команды, чтобы узнать, какое задание выполнить.
Упражнение 2.6
Почему команда
ls -l
выдает четыре связи у каталогаrecipes
?Подсказка: попробуйте ввести
$ ls -ld /usr/you
Чем эта информация полезна?
Упражнение 2.7
В чем состоит разница между
$ mv junk junk1
и
$ cp junk junk1
$ rm junk
Подсказка: установите связь с
junk
и затем используйте ее.
Упражнение 2.8
Команда
cp
не производит копирования во вложенных каталогах, а ограничивается файлами первого уровня вложенности. Каковы будут ее действия, если один из аргументов окажется каталогом? Насколько это хорошо и осмысленно? Обсудите возможные преимущества трех вариантов: включить еще один флаг вcp
, чтобы работать с вложенными каталогами, ввести отдельную командуrcp
(рекурсивнуюcp
) для данного случая или просто предъявить кcp
требование копировать все файлы из каталога, если он встретится среди аргументов (см. гл. 7). Что получат другие программы, если они смогут перемещаться по дереву каталогов?
2.6 Иерархия каталогов
В первой главе рассмотрение иерархии файловой системы, начиная с каталога /usr/you
, носило несколько неформальный характер. Теперь мы хотим изучить ее последовательно, начиная от корня дерева.
Корневой каталог называется /
:
$ ls /
bin
boot
dev
etc
lib
tmp
unix
usr
$
Программа /unix
– это программа ядра UNIX: когда система начинает работу, /unix
считывается с диска в память и начинает выполняться. Все происходит за два шага: вначале считывается файл /boot
, а затем он считывает /unix
. Более подробно о таком процессе раскрутки можно узнать в справочном руководстве по boot(8)
. Остальные файлы каталога /
, по крайней мере в нашей версии, являются каталогами, каждый из которых представляет законченный раздел файловой системы. После дальнейшего краткого обзора иерархии читателю будет предоставлена возможность поэкспериментировать с упоминаемыми здесь каталогами. Чем лучше вы разберетесь в устройстве файловой системы, тем более эффективно сможете ею пользоваться. В табл. 2.1 указаны подходящие места для поиска, хотя некоторые имена каталогов зависят от системы.
/ | Корень файловой системы |
/bin | Основные программы, готовые к выполнению (двоичные) |
/dev | Файлы устройств |
/etc | "Разное" системы |
/etc/motd | Сегодняшнее сообщение при входе в систему |
/etc/passwd | Файл паролей |
/lib | Основные библиотеки и т.п. |
/tmp | Временные файлы; обновляется при запуске системы |
/unix | Операционная система в форме, готовой к выполнению |
/usr | Файловая система пользователей |
/usr/adm | Системная служба: справочная информация и т.п. |
/usr/bin | Команды для пользователей: troff и т.п. |
/usr/games | Игровые программы |
/usr/include | Файлы определений Си-программ, например math.h |
/usr/include/sys | Системные файлы определений Си-программ, например inode.h |
/usr/lib | Библиотеки для Си, Фортрана и т.п. |
/usr/man | Диалоговое справочное руководство |
/usr/man/man1 | Страницы справочного руководства раздела 1 |
/usr/mdec | Диагностика ошибок аппаратуры, программы раскрутки и т.п. |
/usr/news | Служба сообщений пользователей |
/usr/pub | "Всякая всячина": см. ascii(7) и eqnchar(7) |
/usr/src | Исходные тексты служебных функций и библиотек |
/usr/src/cmd | Исходные тексты команд из /bin и /usr/bin |
/usr/src/lib | Исходные тексты библиотечных функций |
/usr/spool | Рабочий каталог для взаимодействующих программ |
/usr/spool/lpd | Временный каталог для печатающего устройства |
/usr/spool/mail | Почтовые ящики |
/usr/spool/uucp | Рабочий каталог программ uucp |
/usr/sys | Исходный текст ядра операционной системы |
/usr/tmp | Альтернативный временный каталог (редко используется) |
/usr/you | Ваш начальный каталог |
/usr/you/bin | Ваши собственные программы |
Таблица 2.1: Интересные каталоги (см. также hier(7)
)
Каталог /bin
вам уже известен: в нем находятся основные программы типа who
или ed
.
Каталог /dev
(device – устройства) мы обсудим в следующем разделе.
Каталог /etc
(et cetera – и т.д.) также уже вам встречался ранее. В нем находится различная служебная информация, например файл паролей, и некоторые системные программы, такие, как /etc/getty
, которая инициирует связь с терминалом для команды /bin/login
, /etc/rc
– это файл команд, выполняющихся после раскрутки системы. В файле /etc/group
содержатся сведения о составе всех групп.
Каталог /lib
(library – библиотека) включает основные части компилятора языка Си, такие, как /lib/cpp
– препроцессор Си, /lib/libc.a
– библиотека стандартных функций Си.
Каталог /tmp
(temporaries – временное) представляет собой хранилище для временных файлов, создаваемых при выполнении программы.
Например, когда вы вызываете редактор, он создает файл с именем типа /tmp/e00512
, что позволяет иметь свою копию редактируемого файла, а не работать с оригиналом. Редактор мог бы, конечно, создать копию в вашем текущем каталоге, но есть причина для преимущественного использования /tmp
: хотя это и маловероятно, в вашем каталоге уже мог присутствовать файл e00512
. Далее каталог /tmp
автоматически очищается при запуске системы, так что в случае системной аварии в вашем каталоге не появится ненужный файл. Часто каталог /tmp
организуется на диске для обеспечения быстрого доступа к нему. Однако здесь возникает проблема: если сразу несколько программ создают файлы в каталоге /tmp
, их файлы могут перепутаться. Именно поэтому редактор ed
выбирает особое имя; оно построено таким образом, чтобы никакая другая программа не могла выбрать то же имя для временного файла. В гл. 5 и 6 будет показан способ достижения этого.
Каталог /usr
называется файловой системой пользователей, хотя он может быть мало связан с файлами настоящих пользователей системы. На своей машине мы используем исходные каталоги /usr/bwk
и /usr/rob
, но у вас часть иерархии, начинающаяся с /usr
, может быть другой. Независимо от того, находятся ли ваши файлы в каталоге, вложенном в /usr
, вы всегда найдете в нем что-нибудь интересное (если нет местной специфики). Так же, как и в каталоге /
, здесь есть каталоги с именами /usr/bin
, /usr/lib
и /usr/tmp
. Эти каталоги имеют назначение, сходное со своими тезками в каталоге /
, но содержат программы, менее критичные для системы. Например, программа nroff
обычно находится в /usr/bin
, а не в /bin
, библиотеки компилятора с Фортрана располагаются в /usr/lib
. Правда, "критичными" для разных систем считаются разные программы. Некоторые системы, такие, как широко распространенная седьмая версия, все программы хранят в /bin
, не имея дела с /usr/bin
. В других системах каталог /usr/bin
разбивается на два каталога в зависимости от частоты использования.
Кроме того, в /usr
есть каталог /usr/adm
со справочной информацией и /usr/dict
, содержащий небольшой словарь (см. spell(1)
). Диалоговое справочное руководство хранится в /usr/man
(см. в качестве примера /usr/man/man1/spell.1
). Если в вашей системе имеются исходные тексты, вы, вероятно, найдете их в /usr/src
.
Вероятно, целесообразно потратить немного времени на исследование файловой системы, особенно каталога /usr
, чтобы вам было понятно, как она устроена и где что можно найти.
2.7 Файлы устройств
В нашем кратком обзоре мы пропустили каталог /dev
по той причине, что файлы в нем дают хорошее общее представление о файлах вообще. Как можно догадаться по его названию, этот каталог содержит файлы устройств ("device" – устройство).
К привлекательным чертам системы 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 fcmem
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 root 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
выдает информацию из индексного дескриптора для файла устройств, но не для обычного файла. Обычному файлу предназначен хранимый в индексном дескрипторе список блоков памяти диска, в которых находится содержимое файла. В случае же файла устройств индексный дескриптор содержит внутреннее имя устройства, включающее его тип (символьное с
или блочное b
) и пару чисел, называемых верхним и нижним числами устройства. К блочным устройствам относятся диски и магнитные ленты, а все остальное: терминалы, принтеры, линии сетевой связи и т.п. – к символьным. Верхнее число устройства обозначает его тип, а нижнее характеризует различные экземпляры устройств одного типа. Например, /dev/tty0
и /dev/tty1
– это два порта одного контроллера терминала, поэтому они имеют одно и то же верхнее число и различные нижние числа.
Файлы для дисков обычно именуются в соответствии с тем вариантом оборудования, которое представлено в системе. Файлы /dev/rp00
и /dev/rp01
названы так потому, что в системе используются дисковые накопители DEC RP06. Есть только один дисковый накопитель, логически поделенный на две файловые системы. Если бы существовал еще один накопитель, связанные с ним файлы имели бы имена /dev/rp10
и /dev/rp11
. Первая цифра обозначает номер накопителя, а вторая показывает, какая его часть используется.
У вас может возникнуть вопрос: почему существует несколько дисковых файлов устройств, а не одно? Исторически так сложилось (и для удобства поддержания), что файловая система была разделена на подсистемы. Файлы в подсистеме доступны через каталог главной системы. Программа /etc/mount
показывает соответствие между файлами устройств и каталогами:
$ /etc/mount
rp01 on /usr
$
В нашем случае каталог root находится на /dev/rp00
(хотя команда /etc/mount
об этом не сообщает), а файловая система пользователей, т.е. файлы из каталога /usr
и вложенных каталогов, находится на /dev/rp01
.
Каталог /root
должен быть доступен системе для выполнения команд. Каталоги /bin
, /dev
и /etc
всегда находятся в корневом каталоге, поскольку при запуске системы доступны только файлы корневого каталога, а такие, как /bin/sh
, необходимы для работы. Во время раскрутки системы все файловые системы проверяются на целостность (см. icheck(8)
или fsck(8)
) и подключаются к корню иерархии файлов. Эта операция подключения называется присоединением и является программистским эквивалентом операции установки пакета дисков на накопитель; обычно она выполняется только суперпользователем. После присоединения /dev/rp01
в качестве /usr
файлы пользователей становятся доступными, как если бы они были частью корневого каталога.
Для обычного пользователя детали операции присоединения подсистемы файлов представляют мало интереса, но здесь есть несколько моментов, относящихся к нашей теме. Во-первых, поскольку подсистемы файлов могут быть присоединены и отсоединены, недопустимо устанавливать связь с файлом из другой подсистемы. Например, нельзя связать программы из общего каталога /bin
с какими-то файлами из каталогов /bin
пользователей, поскольку /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
имеется 21257 свободных блоков. Достаточно ли этого пространства или наступил кризис, зависит от того, как система используется; в одних случаях требуется больше свободного пространства, в других – меньше. Кстати, из всех команд df
, вероятно, обеспечивает наибольшее разнообразие в формате вывода. Результат действия вашей команды df
может выглядеть совершенно иначе.
Рассмотрим теперь некоторые более общие понятия. При входе в систему вы устанавливаете связь вашего терминала с системой и, значит, получаете в каталоге /dev
файл, через который передаются вводимые и принимаемые вами символы. Команда tty
сообщает, какой терминал вы используете:
$ whoami
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
$
Заметьте, что вы владелец устройства и только у вас есть право на чтение с него. Иными словами, никто не может непосредственно читать вводимые вами символы, но выводить на ваш терминал может любой. Во избежание этого можно изменить права доступа к устройству, запретив тем самым другим использовать программу write
для прямой записи или просто воспользоваться командой mesg
.
$ mesg n
Запретим сообщения
$ ls -l /dev/tty0
crw–w– 1 you 1, 12 Sep 28 02:41 /dev/tty0
$ mesg y
Разрешим
$ ls -l /dev/tty0
crw–w–w– 1 you 1, 12 Sep 28 02:42 /dev/tty0
$
Часто бывает удобно использовать имя для ссылки на применяемый терминал, но трудно определить, каково имя вашего терминала. Имя устройства /dev/tty
является синонимом имени терминала, с которого вы вошли в систему, с каким бы терминалом вы ни работали на самом деле:
$ date >/dev/tty
Wed Sep 28 02:42:23 EDT 1983
$
Имя /dev/tty
особенно полезно, если программе необходимо начать диалог с пользователем, в то время когда ее стандартный входной и выходной потоки связаны с файлами, а не с терминалом. Команда crypt
является одной из команд, использующих имя /dev/tty
. "Открытый" текст поступает из стандартного входного потока, а зашифрованная информация направляется в стандартный выходной поток, поэтому команда crypt
читает ключ для шифрования с /dev/tty
:
$ crypt
Enter key:
Введите ключ шифрования
$
В данном примере имя /dev/tty
используется неявно, но все-таки используется. Если бы команда crypt
читала ключ из стандартного входного потока, она бы прочла первую строку из файла cleartext
. Вместо этого она открывает файл /dev/tty
, отключает автоматическое эхо вводимых символов, чтобы ваш ключ не появился на экране, и читает ключ. В гл. 5 и 6 приводится несколько других примеров использования /dev/tty
.
Иногда вы хотите запустить программу, но вам не важен результат ее выполнения. Например, вы могли уже ознакомиться с сегодняшними новостями и не желаете читать их еще раз. Переключение вывода команды news
в файл /dev/null
приведет к игнорированию выходного потока:
$ news >/dev/null
$
Информация, направляемая в /dev/null
, просто пропадает, а программы, читающие из этого файла, сразу получают символ конца файла, поскольку программа чтения всегда возвращает 0 прочитанных байтов.
Обычно файл /dev/null
используют, чтобы отказаться от стандартного выходного потока и сделать видимыми диагностические сообщения. Например, команда time
(time(1)
) сообщает об использованном программой процессорном времени. Результат выдается в стандартный поток диагностики, так что можно хронометрировать команды, производящие преобразование входного потока в выходной, переключая стандартный выходной поток в файл /dev/null
:
$ ls -l /usr/diet/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; она выполняется почти в два раза быстрее команды grep при просмотре больших файлов. Если бы выдача команд egrep
или grep
не была переключена в /dev/null
или текущий файл, пришлось бы ждать, пока сотни тысяч символов "пробегут" на экране, прежде чем появятся нужные нам временные характеристики.
Упражнение 2.9
Познакомьтесь с другими файлами каталога
/dev
, прочитав разд. 4 справочного руководства. В чем состоит разница между/dev/mt0
и/dev/rmt0
? Прокомментируйте возможную пользу применения вложенных каталогов в/dev
для дисков, магнитных лент и т.п.
Упражнение 2.10
Магнитные ленты, записанные в других системах, обычно имеют другие размеры блоков, такие, как 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" (BSTJ, July, 1978). Статья Д. Ритчи ""The evolution of the UNIX time-sharing system" (Symposium on Language Design and Programming Methodology", Sydney, Australia, Sept., 1979) содержит завораживающее описание того, как разрабатывалась и была реализована на исходной PDP-7 файловая система UNIX и как она приобрела нынешнюю форму.
При создании файловой системы UNIX были заимствованы некоторые идеи из системы файлов МАЛТИКС. Содержательное описание последней содержится в книге И. Органика "The MULTICS System: An Examination of its Structure" (MIT Press, 1972).
Статья Б. Морриса и К. Томпсона "Password security: a case history" посвящена интересным сравнениям механизмов паролей во многих системах. Ее можно найти в т. 2В справочного руководства программиста системы UNIX. В том же томе есть статья Д. Ритчи "On the security of UNIX", в которой поясняется, что безопасность системы в большей степени зависит от мер, принимаемых администрацией, чем от деталей таких программ, как
crypt
.