Почему существуют жесткие ссылки?


Ответы:


56

Основным преимуществом жестких ссылок является то, что по сравнению с мягкими ссылками нет размера или скорости. Мягкие ссылки - это дополнительный уровень косвенности поверх обычного доступа к файлам; ядро должно разыменовать ссылку, когда вы открываете файл, и это занимает немного времени. Ссылка также занимает небольшое место на диске для хранения текста ссылки. Эти штрафы не существуют с жесткими ссылками, потому что они встроены в саму структуру файловой системы.

Лучший способ узнать это:

$ ls -id .
1069765 ./
$ mkdir tmp ; cd tmp
$ ls -id ..
1069765 ../

-iВариант lsделает это даст вам номер инодов файла. В системе, где я подготовил приведенный выше пример, я оказался в каталоге с номером индекса 1069765, но конкретное значение не имеет значения. Это просто уникальное значение, которое идентифицирует определенный файл / каталог.

Это говорит о том, что когда мы заходим в подкаталог и смотрим на другую запись в файловой системе .., она имеет тот же номер инода, что и раньше. Этого не происходит, потому что оболочка интерпретирует ..для вас, как это происходит с MS-DOS и Windows. В файловых системах Unix ..это настоящая запись каталога; это жесткая ссылка, указывающая на предыдущий каталог.

Жесткие ссылки - это сухожилия, которые связывают каталоги файловой системы. Когда-то в Unix не было жестких ссылок. Они были добавлены, чтобы превратить исходную плоскую файловую систему Unix в иерархическую файловую систему.

(Подробнее об этом см. Почему «/» имеет запись «..»? )

В системах Unix также довольно часто несколько разных команд реализуются одним и тем же исполняемым файлом. Похоже, это больше не относится к Linux, но к системам, которые я использовал в прошлом cp, mvи rmвсе они были одинаково исполняемыми. Это имеет смысл, если вы подумаете об этом: когда вы перемещаете файл между томами, это фактически копия, за которой следует удаление, поэтому mvуже пришлось реализовать функции двух других команд. Исполняемый файл может выяснить, какую операцию предоставить, поскольку ему передается имя, по которому он был вызван.

Другим примером, распространенным во встроенных Linux-системах, является BusyBox , один исполняемый файл, который реализует десятки команд.

Следует отметить, что в большинстве файловых систем пользователям запрещается делать жесткие ссылки на каталоги. .И ..запись автоматически управляется с помощью кода файловой системы, которая обычно является часть ядра. Ограничение существует, потому что возможно вызвать серьезные проблемы с файловой системой, если вы не будете осторожны с тем, как создавать и использовать жесткие ссылки на каталоги. Это одна из многих причин существования мягких ссылок; они не несут такой же риск.


4
О «Ссылка также занимает небольшое количество места на диске, чтобы удерживать текст ссылки». В современных файловых системах дополнительное пространство не используется для хранения пути ссылки, поскольку сама запись каталога используется для его хранения, по крайней мере, если имя не слишком длинное, чтобы соответствовать. Это называется "быстрые символические
ссылки

Я хотел бы добавить, что некоторые приложения не знают, как обрабатывать мягкие (sym) ссылки, и, таким образом, жесткие ссылки могут быть полезны, чтобы избежать избыточности при настройке их, ссылаясь на те же файлы данных / конфигурации. Примером является ioquake3, который не может следовать за символически связанными файлами pk3, но может следовать за жестко связанными файлами pk3.
Габорист

3
Кроме того, если вы удалите цель символической ссылки, файл исчезнет, ​​а символическая ссылка будет повреждена. Проблема, которая не существует с жесткой ссылкой.
спектры

1
Но у жестких ссылок тоже есть информация - их имена. Так что это должно занять место.
Йозеф Климук

39

Одно из применений жестких ссылок, которое чрезвычайно полезно, - это добавочное резервное копирование в сочетании с rsync. Это экономит много места и делает процедуру восстановления действительно простой. Я использую этот подход для резервного копирования на моих серверах.

Потратьте некоторое время, чтобы прочитать это объяснение .


12

Если после прочтения этой страницы википедии у вас возник вопрос «зачем мне их использовать», то вы не понимаете, что такое жесткие ссылки.

Ссылка является запись каталога , который указывает на блоки на диске. Другими словами, каждый файл в вашей системе имеет хотя бы одну ссылку. Когда вы rmфайл фактический системный вызов unlink(). Удаляет запись каталога. Блоки на диске не изменились, но ссылка исчезла, поэтому файл исчез из списка каталогов.

Вы лично никогда не можете использовать жесткие ссылки, но они есть во всей вашей системе. Например:

$ ls -li /bin | grep 53119771
53119771 -rwxr-xr-x 3 root root  26292 2010-08-18 10:15 bunzip2
53119771 -rwxr-xr-x 3 root root  26292 2010-08-18 10:15 bzcat
53119771 -rwxr-xr-x 3 root root  26292 2010-08-18 10:15 bzip2

Вы можете видеть это bunzip2, bzcatи bzipвсе используют один и тот же индекс. По сути, это один файл с тремя именами. У вас может быть три копии файла, но почему? Это только израсходовало бы дисковое пространство без необходимости.


12
Но есть также несколько символических ссылок /bin, я думаю, это один из источников путаницы. Почему иногда исполняемые файлы будут символическими, а иногда - жесткими?
Дмитрий Пашкевич

16
Этот ответ не дает никаких оснований для использования жестких ссылок над мягкими ссылками.
Марк Амери

8

Есть любое количество применений. Я использую их для создания файловых блокировок. Системный вызов link (2) является атомарным, в отличие от большинства других системных вызовов.

Другое использование в rsnapshot, где резервные копии создаются с использованием жестких ссылок для уменьшения объема дискового пространства. Если файл не изменился, то файл жестко связан с более старыми экземплярами файла, а измененные файлы копируются заново.

Я также использую их для замены файлов конфигурации на серверах: rm file.cfg && ln ~/tmp/file.cfg file.cfgзатем файлы ~ / tmp / * можно безопасно удалить.


1
Почему отдельный, lnа rmне просто mv?
Томми

6

Чтобы добавить к нескольким хорошим обсуждениям, уже присутствующим ...

  • Способ, которым доступ к ресурсам для программ реализован в Unix (т. Е. «Все является файлом» ), означает, что инфраструктура для обработки множественных ссылок на файл требуется для работы ОС вообще, поэтому здесь нет дополнительных затрат.
  • То, как каталоги были реализованы в исходных файловых системах Unix (т. Е. Список (inode, name)пар фиксированного формата означает, что в файловой системе нет дополнительных затрат на наличие жестких ссылок (ну, пока мы предотвращаем циклы, не допуская жесткую ссылку на каталоги (кроме .и ..(разве это начинает кому-то еще нравиться?)))

поэтому мы получаем их бесплатно.


2

Я, вероятно, должен охватить сценарий ловушек жестких ссылок. Жесткая ссылка будет представлять собой тот же файл с другим именем и / или другим местоположением, если существует исходный связанный файл . Неправильно даже думать о файле как о «оригинальном»: оба являются самостоятельными записями каталога, и оба (или более) - все равные одноранговые узлы. Для долгоживущих файлов это может быть благословением, но если одна из пары будет удалена и затем создана, даже с тем же именем и содержимым, файлы будут разделены.

Предположим, вы создали жесткую ссылку /foo/myfileна /repo/myfile. Оба указателя на одни и те же данные файла; измените одно, другое изменится. Но предположим, что /repoслучается с хранилищем Git. Если вы проверите ветку, которая не содержит myfileв нем, /repo/myfileудаляется. В этот момент /foo/myfileстановится простой копией /repo/myfile, как бы в тот момент другая пара не была связана. Легко даже не заметить, когда вы переключаетесь между ветвями, что файл репертуара изменяется, но, когда вы извлекаете оригинальную ветку, новый файл/repo/myfileсоздан Git. Если бы вы не обратили внимания, вы бы удивились, почему два файла теперь имеют разное содержимое, хотя это легко понять, так как отношения жестких ссылок между файлами не имеют представления об их именах. Напротив, мягкая ссылка выживет в этом цикле удаления-создания.

С другой стороны, программное обеспечение, использующее жесткие ссылки, четко осознает это, и Git является ярким примером. Git клонирует репозиторий в той же файловой системе практически бесплатно, потому что он использует жесткие ссылки по умолчанию вместо копирования файлов. Для Git жесткая ссылка является идеальным вариантом использования, потому что его файлы объектов и пакетов никогда не меняются, поэтому один клон репозитория никогда не изменит другой (Git знает, что не нужно жестко связывать изменяемые файлы), и любой из клонов может быть удаляется без каких-либо мер предосторожности: нет необходимости отслеживать, какой из них является «оригинальным» и действительно содержит файлы: любая из жестких ссылок является равноправным партнером и «содержит» полный файл. Мягкие ссылки просто не будут работать здесь.

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

Суть в том, что во многих случаях использования либо тип ссылки работает одинаково хорошо, но в том или ином типе это выгодно. Эффективность, упомянутая во многих ответах здесь, вероятно, очень мало заботит современные машины и файловые системы, если только вы не копируете файловую систему на микросхеме FLASH маленького встроенного контроллера. В функциональных различиях являются более важными, и , как правило , диктуют технические ограничения и окончательный выбор:

  • Жесткая ссылка «источник» может быть безопасно перемещена, в то время как мягкая ссылка будет разорвана.
  • Жесткая ссылка неотличима от файла, с которым она была связана, и файл жив, пока жива любая из жестких ссылок; мягкая связь асимметрична.
  • Жестко связанный одноранговый узел выходит из связанной группы в случае удаления и повторного создания, но мягкая ссылка не теряет своей цели.
  • Мягкая ссылка может пересекать файловые системы, жесткая ссылка не может.
  • Мягкая ссылка может указывать на каталог, жесткая ссылка обычно не может (и практически всегда не должна).

Кроме того, я должен указать, что библиотечный вызов, который удаляет файл, вызывается unlink()по причине! Каждая запись в каталоге - это просто изначально жесткая ссылка на свой индекс.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.