В 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 все еще не нужно).