Я читал в учебниках, что Unix / Linux не разрешает жесткие ссылки на каталоги, но разрешает мягкие ссылки. Это потому, что когда у нас есть циклы и если мы создаем жесткие ссылки и через некоторое время удаляем исходный файл, он будет указывать на какое-то мусорное значение?
Если циклы были единственной причиной запрета жестких ссылок, то почему разрешены мягкие ссылки на каталоги?
filesystems
directory
symlink
hard-link
user3539
источник
источник
..
указать? Особенно после удаления жесткой ссылки на этот каталог, в каталог, на который указывает..
? Это должно указать куда-то...
не нужно физически существовать на любом диске. В любом случае, операционная система отслеживает текущий рабочий каталог, поэтому относительно просто хранить список инодов, связанных с каждым процессом cwd, и ссылаться на него, когда он видит использование..
. Конечно, это будет означать, что символические ссылки нужно создавать с учетом этого, но вы уже должны быть осторожны, чтобы не нарушать символические ссылки, и я не думаю, что дополнительное правило сделает их бесполезными.Ответы:
Это просто плохая идея, так как невозможно определить разницу между жесткой ссылкой и оригинальным именем.
Разрешение жестких ссылок на каталоги нарушило бы структуру ориентированного ациклического графа файловой системы, возможно, создавая петли каталогов и висячие поддеревья каталогов, что могло бы привести к
fsck
любым ошибкам обходчиков дерева файлов.Во-первых, чтобы понять это, давайте поговорим об инодах. Данные в файловой системе хранятся в блоках на диске, и эти блоки собираются вместе с помощью inode. Вы можете думать об иноде как о файле. У inode нет имен файлов. Вот где приходят ссылки.
Ссылка - это просто указатель на индекс. Каталог - это индекс, который содержит ссылки. Каждое имя файла в каталоге - это просто ссылка на индекс. Открытие файла в Unix также создает ссылку, но это другой тип ссылки (это не именованная ссылка).
Жесткая ссылка - это просто дополнительная запись каталога, указывающая на этот индекс. Когда вы
ls -l
, число после разрешений является именованным количеством ссылок. Большинство обычных файлов будут иметь одну ссылку. Создание новой жесткой ссылки на файл заставит оба имени файла указывать на один и тот же индекс. Примечание:Теперь вы можете ясно видеть, что нет такой вещи, как жесткая ссылка. Жесткая ссылка такая же, как и обычное имя. В приведенном выше примере,
test
илиtest2
, что является исходным файлом, а какая жесткая ссылка? В конце концов, вы не можете сказать (даже по меткам времени), потому что оба имени указывают на одно и то же содержимое, один и тот же индекс:-i
Флагls
показывает иноды номера в начале строки. Обратите внимание, чтоtest
иtest2
есть один и тот же номер инода, ноtest3
другой.Теперь, если вам разрешено делать это для каталогов, два разных каталога в разных точках файловой системы могут указывать на одно и то же. Фактически, subdir может указывать на своего деда, создавая цикл.
Почему этот цикл вызывает беспокойство? Потому что когда вы пересекаете, нет никакого способа обнаружить, что вы зацикливаетесь (без отслеживания номеров инодов во время прохождения). Представьте, что вы пишете
du
команду, которую необходимо выполнить через подпапки, чтобы узнать об использовании диска. Как быdu
знать, когда он попадет в петлю? Это подвержено ошибкам и много бухгалтерии,du
что нужно сделать, просто чтобы выполнить эту простую задачу.Симлинки - это совершенно другой зверь в том смысле, что они представляют собой особый тип «файла», за которым обычно следуют многие API файловой системы. Обратите внимание, что символическая ссылка может указывать на несуществующий пункт назначения, потому что они указывают по имени, а не напрямую на индекс. Эта концепция не имеет смысла для жестких ссылок, потому что само существование «жесткой ссылки» означает, что файл существует.
Так почему же можно
du
легко справиться с символическими ссылками, а не с жесткими ссылками? Выше мы увидели, что жесткие ссылки неотличимы от обычных записей каталога. Симлинки, однако, особенные, обнаруживаемые и пропускаемые!du
замечает, что символическая ссылка является символической ссылкой, и пропускает ее полностью!источник
Allowing hard links to directories would break the directed acyclic graph structure of the filesystem
, Можете ли вы объяснить больше о проблеме с циклами, используя жесткие ссылки? Почему это нормально с символическимиЗа исключением точек монтирования, каждый каталог имеет один и только родитель:
..
.Один из способов
pwd
- проверить устройство: inode для «.» а также '..'. Если они совпадают, вы достигли корня файловой системы. В противном случае, найдите имя текущего каталога в родительском, поместите его в стек и начните сравнивать '../.' с '../ ..', затем '../../.' с '../../ ..' и т. д. Как только вы дойдете до корня, начните выталкивать и печатать имена из стека. Этот алгоритм основан на том факте, что каждый каталог имеет одного и только одного родителя.Если разрешены жесткие ссылки на каталоги, на кого должен
..
указывать один из нескольких родителей ? Это одна из веских причин, по которым жесткие ссылки на каталоги запрещены.Символьные ссылки на каталоги не вызывают этой проблемы. Если программа хочет, она может выполнить
lstat()
каждую часть имени пути и обнаружить, когда встречается символическая ссылка.pwd
Алгоритм возвращает истинный абсолютный путь к файлу для целевого каталога. Тот факт, что где-то есть фрагмент текста (символическая ссылка), указывающий на целевой каталог, в значительной степени не имеет значения. Существование такой символической ссылки не создает петлю в графе.источник
..
что это своего рода виртуальная жесткая ссылка на родителя, то нет технической причины, по которой у цели ссылки может быть только одна другая ссылка.pwd
просто придется использовать другой алгоритм для разрешения пути.Вы можете использовать bind mount для симуляции жестких ссылок на каталоги
источник
Я хотел бы добавить еще несколько моментов по этому вопросу. Жесткие ссылки на каталоги разрешены в Linux, но ограниченным способом.
Один из способов проверить это, когда мы перечисляем содержимое каталога, мы находим два специальных каталога "." а также "..". Как мы знаем "." указывает на тот же каталог, а ".." указывает на родительский каталог.
Итак, давайте создадим дерево каталогов, где «a» является родительским каталогом, у которого каталог «b» является дочерним.
Запишите индекс каталога "а". И когда мы делаем
ls -la
из каталога «а», мы можем видеть, что «.» каталог также указывает на тот же индекс.И здесь мы можем обнаружить, что каталог «а» имеет три жестких ссылки. Это связано с тем, что индекс 797358 имеет три жесткие ссылки на имя "." внутри каталога "a" и имя как ".." внутри каталога "b" и один с именем "a" itslef.
Таким образом, здесь мы можем понять, что жесткие ссылки существуют только для каталогов, связанных с их родительскими и дочерними каталогами. Таким образом, каталог без дочерних элементов будет иметь только две жесткие ссылки, и поэтому каталог «b» будет иметь только две жесткие ссылки.
Одна из причин, по которой жесткое связывание каталогов свободно предотвращается, заключается в том, чтобы избегать бесконечных циклов ссылок, которые могут запутать программы, пересекающие файловую систему.
Поскольку файловая система организована как дерево и дерево не может иметь циклическую ссылку, этого следует избегать.
источник
Ничто из перечисленного не является реальной причиной запрещения жестких ссылок на каталоги; каждую проблему довольно легко решить:
Реальная причина (как намекают @ Турбьёрна Равн Andersen) приходит , когда вы удалите каталог , который имеет несколько родителей, из каталога , на который указывает
..
:На что
..
сейчас следует указывать?Если каталог удален из его родителя, но количество ссылок по-прежнему больше, чем
0
тогда, должно быть что-то, где-то еще указывающее на него. Вы не можете оставить..
указывать ни на что; на многие программы полагается..
, поэтому системе придется обходить всю файловую систему, пока она не найдет первое, что указывает на удаленный каталог, просто для обновления..
. Либо так, либо файловая система должна была бы поддерживать список всех каталогов, указывающих на жестко связанный каталог.В любом случае, это может привести к снижению производительности и дополнительным осложнениям для метаданных файловой системы и / или кода, поэтому разработчики решили не допустить этого.
источник
..
), обновитесь,..
чтобы указать на одного из других родителей в списке.a/..
это всегда будет означать.
. Вот как работают URL, кстати. Это браузер, который разрешает «..» еще до того, как он попадает на сервер. И это прекрасно работает.Создание жесткой ссылки на каталоги было бы необратимым. Предположим, у нас есть:
Я жестко связываю это с
/dir2
.Так что
/dir2
теперь также содержит все эти файлы и каталогиЧто если я передумаю? Я не могу просто
rmdir /dir2
(потому что это не пусто)И если я рекурсивно удаляю в
/dir2
... он тоже будет удален/dir1
!ИМХО, это в значительной степени достаточная причина, чтобы избежать этого!
Редактировать :
Комментарии предлагают удалить каталог, сделав
rm
на нем. Ноrm
в непустом каталоге происходит сбой, и это поведение должно сохраняться независимо от того, является ли каталог жестким или нет. Так что вы не можете простоrm
отключить его. Для этого потребуется новый аргументrm
, просто чтобы сказать: «если индекс узла имеет счетчик ссылок> 1, то только отсоединить каталог».Что, в свою очередь, нарушает другой принцип наименьшего удивления: это означает, что удаление только что созданной жесткой ссылки на каталог не совпадает с удалением обычной жесткой ссылки на файл ...
Я перефразирую свое предложение: без дальнейшей разработки создание жесткой ссылки было бы необратимым (поскольку никакая текущая команда не может обработать удаление, не будучи несовместимым с текущим поведением)
Если мы позволим доработать кейс для разработки, количество подводных камней и риск потери данных, если вы недостаточно осведомлены о том, как работает система, такое развитие событий подразумевает ИМХО достаточную причину для ограничения жестких ссылок на каталоги.
источник
rm
делает в любом случае (unlink). См .: unix.stackexchange.com/questions/151951/… Это действительно не проблема, равно как и с файлами с жесткими ссылками . Отмена ссылок просто удаляет именованную ссылку и уменьшает количество ссылок. Тот факт, чтоrmdir
не удаляются непустые каталоги, не имеет значения - он не будет делать этоdir1
ни для чего . Жесткие ссылки не являются копиями данных, они представляют собой один и тот же фактический файл, поэтому фактически «удаление» файла dir2 приведет к удалению списка каталогов для dir1. Вы всегда должны будете отменить связь.rm
в каталоге не отсоединяйте его, если он не пустой. Смотрите Редактировать.Это хорошее объяснение. Относительно "Кто из нескольких родителей должен .. указать на?" Одним из решений было бы для процесса поддерживать свой полный путь wd, либо в виде inode, либо в виде строки. Иноды будут более надежными, так как имена могут быть изменены. По крайней мере, в прежние времена для каждого открытого файла существовал внутренний индекс, который увеличивался при каждом открытии файла, уменьшался при закрытии. Когда он достигнет нуля, хранилище, на которое он указывал, будет освобождено. Когда файл больше не был открыт никому, он (копия в ядре) был бы заброшен. Это позволило бы сохранить путь действительным, если какой-либо другой процесс переместил каталог в другой каталог, в то время как подкаталог находился в пути другого процесса. Подобно тому, как вы можете удалить открытый файл, но он просто удаляется из каталога,
Жесткие ссылки на каталоги раньше свободно разрешались в Bell Labs UNIX, по крайней мере, V6 и V7. Не знаю о Беркли или более поздних версиях. Флаг не требуется. Не могли бы вы сделать петли? Да, не делай этого. Это очень ясно, что вы делаете, если вы делаете петлю. Если вы будете практиковать завязывание узлов вокруг шеи, пока вы ждете своей очереди, чтобы выпрыгнуть из самолета, если у вас другой конец удобно подвешен на крюке на насадке.
То, что я надеялся сделать с этим сегодня, это жестко связать lhome с home, чтобы я мог иметь доступ к / home / admin независимо от того, был ли / home скрыт с помощью автомаута над home, причем этот автомонтирование имеет символическую ссылку с именем admin на / lhome. / administ. Это позволяет мне иметь административную учетную запись, которая работает независимо от состояния моей основной домашней файловой системы. Это IS эксперимент для Linux, но я думаю , что узнал в свое время на основе UCB в SunOS , что automounts делаются на уровне строки ASCII. Трудно понять, как их можно было бы сделать иначе, как слой поверх любой произвольной ФС.
Я читал в другом месте, что. и .. больше не являются файлами в каталоге. Я уверен, что для всего этого есть веские причины, и многое из того, что нам нравится (например, возможность монтировать NTFS), возможно благодаря таким вещам, но некоторая элегантность UNIX была в реализации. Именно такие преимущества, как универсальность и гибкость, обеспеченные этой элегантностью, позволили ей быть настолько прочной и выдерживать в течение четырех десятилетий. По мере того, как мы теряем изящные реализации, в конечном итоге он становится похожим на Windows (надеюсь, я ошибаюсь!). Кто-то тогда создаст новую ОС, основанную на элегантных принципах. Что-то думать о. Возможно, я ошибаюсь, я (очевидно) не знаком с текущей реализацией. это является Удивительно, насколько 30-летнее понимание применимо к Linux ... большую часть времени!
источник
.
и..
это не жесткие ссылки в файловой системе для современных файловых систем. Однако драйвер файловой системы подделывает их. Именно эти файловые системы останавливают жесткие ссылки на каталоги. Для старых файловых систем это было возможно (но опасно). Чтобы сделать то, что вы пытаетесь, посмотритеmount --bind
, посмотрите такжеmount --make…
и, возможно, контейнеры.Исходя из того, что я понял, основная причина заключается в том, что полезно иметь возможность изменять имена каталогов, не портя запущенные программы, которые используют свой рабочий каталог для ссылки на другие файлы. Предположим, вы использовали Wine для запуска
~/.newwineprefix/drive_c/Program Files/Firefox/Firefox.exe
и~/.wine
вместо него хотите переместить весь префикс . Если по какой-то странной причине Firefoxdrive_c/windows
обращался к нему../../windows
, ссылаясь на него , переименование~/.newwineprefix
прерывает реализации,..
которые отслеживают родительский каталог как текстовую строку вместо inode.Хранить inode одного родительского каталога должно быть проще, чем пытаться отслеживать каждый путь как текстовую строку, так и серию inode.
Другая причина в том, что неправильно работающие приложения могут создавать циклы. Приложения, работающие с приложениями, должны иметь возможность проверять, является ли индекс перемещаемого каталога тем же, что и индекс любого из вложенных каталогов, в которые он перемещается, точно так же, как вы не можете переместить каталог в себя, но это не может быть применено принудительно. на уровне файловой системы.
Еще одна причина может заключаться в том, что если бы вы могли создавать жесткие ссылки на каталоги, вы бы хотели запретить жесткую ссылку на каталог, который вы не можете изменить.
find
имеет соображения безопасности, потому что он используется для очистки файлов, созданных другими пользователями, из временных каталогов, что может вызвать проблемы, если пользователь переключает реальный каталог для символической ссылки во времяfind
вызова другой команды. Возможность жесткого связывания важных каталогов вынудит администратора добавить дополнительные тесты,find
чтобы избежать их влияния. (Хорошо, вы уже не можете сделать это для файлов, поэтому эта причина недействительна.)Еще одна причина заключается в том, что хранение inode родительского каталога может обеспечить дополнительную избыточность в случае повреждения или повреждения файловой системы. Если вы хотите
..
перечислить все родительские каталоги, которые жестко связаны с этим, так что другой, произвольный родительский элемент может быть легко найден, если текущий разделен, не только вы нарушаете идею о том, что жесткие ссылки равны, вы должны изменить способ Файловая система хранит и использует inode. Если бы программы обрабатывали пути как серию (уникальную для каждой жесткой ссылки) инодов каталогов, этого можно было бы избежать, но вы не получите избыточности в случае повреждения файловой системы.источник