В Unix, как правило, файл представляет собой некоторую запись в таблице файлов. Существуют различные виды файлов: обычные файлы, устройства, символические ссылки, двери, каналы, сокеты, каталоги ...
Номер ls -i
индекса (который вы можете видеть в выходных данных ) является индексом в этой таблице.
Теперь вы обращаетесь к файлам не по индоду, а по пути . Путь представляет собой цепочку из каталога записей. Вы заметите, что мы говорим не о папке, а о каталоге здесь. Потому что это то, что каталог (подумайте о телефонном справочнике).
Каталог - это особый вид файла, который присваивает имена нескольким индексам. Запись в каталоге - это отображение имени на индекс.
Данный файл (индекс) может иметь более одного имени в одном каталоге (точно так же, как может быть более одного имени в номере телефона), а также может иметь имена (записи) в более чем одном каталоге. Это так называемые ссылки, также известные как жесткие ссылки, которые можно различить с помощью мягких ссылок (особый тип файла, который является указателем на путь).
Файл (inode) отслеживает количество имеющихся у него ссылок (записей в любом каталоге), поэтому, когда число достигает 0 (когда оно не связано с последним каталогом, в котором оно было указано), оно освобождается.
Это то число (количество ссылок), которое отображается в ls -l
выводе.
Когда файл , не являющийся каталогом создается в первый раз (с open
или creat
(или bind
или mknod
для некоторых типов файлов) системные вызовы), это делается путем предоставления путь к новому файлу (например "/a/b"
). Затем происходит новый файл, выделяется индекс и добавляется новая запись в каталог, связанный с "a"
именем в "/"
корневом каталоге. Это начальная ссылка, поэтому количество ссылок равно единице.
Дополнительные ссылки могут быть добавлены позже с помощью link()
системного вызова ( ln
команда). А ссылки можно удалить с помощью unlink()
системного вызова ( rm
команда).
Вы заметите, что файлы типа directory обычно имеют количество ссылок, большее или равное 2.
Теперь, когда вы создаете каталог, вы вызываете mkdir()
системный вызов. Нечто подобное mkdir("/a/b")
. Затем он выделяет новый файл типа directory. В этом новом каталоге он автоматически создает две записи:
"."
( точка для каталога ). Который является ссылкой на себя. Таким образом, количество ссылок теперь равно 1.
".."
(для каталога «s каталога ). Который является ссылкой на "/a"
. Таким образом, количество ссылок "/a"
увеличивается на один
Затем этот новый каталог связывается "/a"
( "/a"
для него добавляется запись ), поэтому его счетчик ссылок теперь равен 2. Если "/a/b/c"
каталог создается из-за ".."
записи в "/a/b/c"
, счетчик ссылок "/a/b"
станет 3.
Большинство Unices ограничивают создание дальнейших ссылок на каталог, потому что они могут вызвать проблемные циклы. Когда они разрешают доступ link()
к каталогу, как правило, только суперпользователь может это сделать.
Некоторые файловые системы, например, btrfs
отходят от этой традиционной структуры каталогов. Вы заметите, что ссылки на каталоги в btrfs
файловых системах всегда едины, даже если эти каталоги содержат "."
запись с тем же номером инода, что и в них.
Тот факт, что количество ссылок традиционно составляет 2 плюс количество подкаталогов, имеет свое применение. Например, в:
find . -name '*.c' -print
Если .
не содержит подкаталогов, но содержит миллионы файлов. Проверяя количество ссылок .
, find
можно узнать, что нет subdir. Таким образом, все, find
что нужно сделать, это прочитать содержимое каталога и сообщить о записях, которые заканчиваются .c
(например, grep '\.c$'
файл размером в несколько мегабайт, ничего страшного). В противном случае find
пришлось бы проверять тип каждого отдельного файла, чтобы увидеть, есть ли в нем каталоги, в которые можно перейти (что приведет к такому количеству lstat()
системных вызовов). Конечно, этот тип оптимизации не работает btrfs
(хотя в современных версиях Linux тип файлов также сохраняется в записи каталога для некоторых файловых систем (включая btrfs
) и возвращается getdents(2)
системным вызовом, используемым для получения списка записей. в каталоге, такlstat
все еще не нужно).