Главная » Программирование для UNIX » Индексные дескрипторы UNIX

0

Файл имеет  несколько компонентов: имя, содержимое, служебную информацию, такую как права доступа и время модификации. Служебная  информация хранится в индексном дескрипторе («inode», раньше было  «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

$

Команда ls  –t сортирует файлы по времени, по умолчанию это время последнего изменения.  Параметр –t  может применяться  совместно с параметром –c или  –u для  определения порядка изменения индексных дескрипторов или чтения файлов:

$ ls recipes

cookie 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,  но и потому, что можно сказать, что индексные дескрипторы – это есть  файлы. Единственное назначение иерархии каталогов заключается в предоставлении удобных имен фай лов. Внутреннее системное имя  файла – это номер его индексного дескриптора (i-number),  хранящего информацию о файле. Десятичные значения номеров индексных дескрипторов показывает команда ls  –i:

$ date >x

$ ls -i 15768 junk 15274  recipes 15852 x

$

Перед  именем файла, в первых двух байтах записи каталога, как раз и хранится номер его индексного дескриптора. Команда od –d, в отличие от восьмеричного побайтного, выводит десятичный дамп  парами, позволяя увидеть значения i-number.

$ od -c  .

0000000    4     ;   .  \0    \0    \0    \0    \0    \0    \0    \0    \0    \0    \0    \0    \0

0000020 273     (   .   .  \0    \0    \0    \0    \0    \0    \0    \0   \0    \0    \0    \0

0000040 252     ;   r   e     c     i   p     e     s    \0    \0    \0    \0    \0    \0    \0

0000060 230     =     j   u     n     k   \0    \0    \0    \0    \0    \0    \0    \0    \0    \0

0000100 354     =     x   \0    \0    \0    \0    \0    \0    \0    \0    \0   \0    \0    \0    \0

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 в действительности удаляет не индексные дескрипторы, а записи в каталоге, то есть ссылки. И только когда исчезнет  последняя ссылка на файл, система удаляет индексный дескриптор, а значит и сам файл.

Если  номер  индексного дескриптора в элементе каталога равен  нулю, это означает, что данная ссылка была  удалена, чего  нельзя сказать о содержимом файла – возможно, где-то  еще остались ссылки на него. Убедимся в том, что значение i–number обнуляется при удалении файла:

$ 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

$

Следующий созданный в этом каталоге файл займет пустующее место, хотя, скорее всего, значение i-number будет другим.

Ссылка на существующий файл создается командой ln:

$ ln  старый5файл новый5файл

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

$ 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 счетчик ссылок вернулся к прежнему значению 1. Как уже говорилось, удаление файла командой rm лишь стирает ссылку, а сам файл существует, пока  на него есть хотя бы одна  ссылка. Конечно, большинству файлов достаточно одной  ссылки, но и здесь мы видим, как простая идея  дает исключительную гибкость.

Предостережение  для   торопливых:  как  только  удалена  последняя ссылка на файл, его данные теряются. Удаленные файлы попадают в печь, а не  в мусорную корзину, и  восстановить их  из  пепла уже  не удастся.  (Есть, однако, призрачная  надежда на  восстановление.  В большинстве крупных  систем периодически выполняется  резервное копирование для хранения изменившихся файлов в безопасном месте, обычно  на магнитной ленте, откуда их можно восстановить. Для собственной безопасности и  спокойствия поинтересуйтесь,  как часто  выполняется копирование в вашей системе. Если  таковое отсутствует, будьте осторожны, сбой диска может обернуться катастрофой.)

Ссылки на  файлы  удобны, когда  требуется  одновременный  доступ  пользователей к файлу, но иногда целесообразно иметь отдельную копию – второй файл с той же информацией. Перед редактированием документа полезно сделать копию, чтобы  иметь возможность отказаться от изменений и вернуться к оригиналу. Ссылка здесь не поможет, так  как все ссылки ведут  к уже измененному файлу. Копирование выполняется командой 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

$

Значение i-number файла sameoldjunk показывает, что это тот же самый файл, что и прежний junk, изменилось только его имя, то есть элемент каталога,  связанный  с  индексным  дескриптором,  имеющим номер  15 768.

Было реализовано перемещение файла внутри одного  каталога, но такие  перестановки  возможны и  между каталогами.  Часто  несколько ссылок с одинаковыми именами, расположенные в разных каталогах, указывают  на  один  файл, например, когда несколько  пользователей работают с одной  и той  же программой или  документом. Команда mv может перемещать каталог или файл из одного каталога в другой. Для

таких часто повторяющихся действий в командах mv и cp предусмотрен специальный синтаксис:

$ mv  (или cp)  файл1 файл2 … каталог

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

$ cp /usr/src/cmd/ed.c .

и получить собственную копию исходного текста для  экспериментов.

А если собираетесь поработать над оболочкой, то создайте каталог

$ mkdir  sh

$ cp /usr/src/cmd/sh/* sh

и командой cp скопируйте туда  ее исходные файлы (здесь  предполагается, что в /usr/src/cmd/sh нет подкаталогов, так  как команда cp не сумеет их создать). В некоторых системах ln также может принимать несколько аргументов и последним тоже  должно быть имя каталога. А в некоторых системах mv, cp и ln сами являются ссылками на один и тот же файл, который проверяет, по какому имени к нему обращаются, и в зависимости от этого выбирает нужное действие.

Упражнение 2.6. Почему команда ls  –l сообщает о 4 ссылках на reci– pes? Подсказка: используйте

$ ls -ld /usr/you

Чем полезна эта информация? ~

Упражнение 2.7. В чем разница между

$ mv  junk  junk1

и

$ cp junk  junk1

$ rm junk

Подсказка: создайте ссылку на junk и проверьте ее значение. ~

Упражнение 2.8.  Команда cp копирует только файлы первого уровня иерархии и не может копировать подкаталоги. Что  она сделает, если один из аргументов окажется каталогом? Удобно ли это? Сравните три  способа: параметр команды cp для  перехода в подкаталоги, отдельную команду rcp (рекурсивное копирование) и копирование каталогов командой cp по умолчанию. За дополнительной информацией о реализации   этой  возможности  обратитесь к главе 7. Какую пользу другим программам принесла бы возможность прохода по дереву  каталогов? ~

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

По теме:

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