Варианты использования для жестких ссылок? [закрыто]


40

В каких ситуациях желательно использовать жесткую ссылку, а не мягкую? Лично я никогда не сталкивался с ситуацией, когда я хотел бы использовать жесткую ссылку на мягкую ссылку, и единственный случай использования, с которым я столкнулся при поиске в Интернете, - это дедупликация идентичных файлов .


4
Ниже приведены хорошие ответы, но рассмотрим (спорный) исторический контекст. Когда Unix был новым, дисководы были медленными и имели ограниченную емкость и буферизацию. Жесткая ссылка была просто еще одной прямой записью в файловой системе на тот же файл. Доступ к ls или, как вы любите это называть, список , не имеет значения. Если вы сделали список мягкой ссылкой, то для его использования потребуется найти его в каталоге, прочитать специальный файл с именем list , увидеть, что вам нужен файл ls , найти ls в каталоге и прочитать фактический файл ls с диска. Огромная разница в производительности!
RichF

16
Первая жесткая ссылка на файл чертовски полезна.
Стоп Harm Monica

@OrangeDog: Да, но вам нужно только поле количества ссылок в inode, если вы хотите поддерживать несколько ссылок. (Вам может понадобиться флаг для версии inode в памяти для обработки несвязанного, но все еще открытого случая. Fsck после сбоя без ведения журнала все равно придется искать inode без ссылок в любом случае.)
Peter Cordes

1
Семантика каталога POSIX должна была бы быть разработана по-другому: ..всегда тот же самый inode, что и .в родительском каталоге. Вещи вроде findмогут проверить, что link-count = 2, чтобы обнаружить statконечные каталоги, и избежать записи в readdir для поиска подкаталогов. Но это лишь второстепенная функция, включаемая поддержкой жестких ссылок на файлы, не относящиеся к каталогам (обычный, символическая ссылка, устройство, сокет и именованный канал). (Да, символические ссылки имеют свой собственный индекс и могут быть
Питер Кордес

1
Одной из причин использования жестких ссылок я не видел в своем обзоре SO, "глобального" характера. Представьте себе файловую систему, где файлы, как правило, небольшие (скажем, в основном это короткие заметки), но для того, чтобы все было организовано, вам могут понадобиться указатели на один и тот же файл в разных местах. С символическими ссылками каждый указатель использует индекс. Такие файловые системы могут уже иметь проблему с исчерпанием inode. Использование жестких ссылок в качестве указателей помогает с этой проблемой. количество инодов ограничено; названий для них нет (по крайней мере, не таким же образом).
mathguy

Ответы:


27

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

Медиа-коллекция, в которой все файлы хранятся в одном, плоском, каталоге и сортируются в другие каталоги на основе различных критериев, таких как: год, тема, исполнитель, жанр и т. Д. Это может быть личная коллекция фильмов или коллектив коммерческой студии. работает. По сути, файл сохранен, вряд ли будет изменен и отсортирован, возможно, в нескольких местах по ссылкам.

Имейте в виду, что понятия «оригинал» и «копия» неприменимы к жестким ссылкам: каждая ссылка на файл является оригиналом, в обычном смысле слова «копия» не существует. Однако для описания варианта использования термины имитируют логику поведения.

«Оригинал» сохраняется в каталоге «каталог», а отсортированные «копии» жестко связаны с этими файлами. Атрибуты файла в каталогах сортировки могут быть установлены в r / o, предотвращая любые случайные изменения имен файлов и отсортированной структуры, в то время как атрибуты в каталоге каталога могут быть r / w, что позволяет изменять их по мере необходимости. (Это могут быть музыкальные файлы, в которых некоторые проигрыватели пытаются переименовывать и реорганизовывать файлы на основе тегов, встроенных в медиафайл, из пользовательского ввода или поиска в Интернете.) Кроме того, поскольку атрибуты каталогов «copy» могут отличаться от «оригинальный» каталог, отсортированная структура может быть сделана доступной для группы или мира с ограниченным доступом, в то время как основной «каталог» доступен только для основного пользователя, с полным доступом. Однако сами файлы всегда будут иметь одинаковые атрибуты на всех ссылках на этот индекс. (ACL может быть изучен, чтобы улучшить это, но не моя область знаний.)

Если оригинал переименовывается или перемещается (например, один каталог «каталог» становится слишком большим для управления), жесткие ссылки остаются действительными, программные ссылки нарушаются. Если «копии» перемещены и программные ссылки являются относительными, то программные ссылки, опять же, будут сломаны, а жесткие ссылки не будут.

Примечание. Кажется, что существует несогласованность в том, как различные инструменты сообщают об использовании диска при использовании программных ссылок. С жесткими ссылками, однако, это кажется последовательным. Таким образом, при наличии 100 файлов в каталоге, отсортированных по совокупности «тегов», легко может быть 500 связанных «копий». (Для коллекции фотографий, скажем, даты, фотографа и в среднем 3 «предметных» тега.) Например, Dolphin сообщит, что это 100 файлов для жестких ссылок и 600 файлов, если используются программные ссылки. Интересно, что в любом случае он сообщает об одном и том же использовании дискового пространства, поэтому он выглядит как большая коллекция небольших файлов для софт-ссылок и небольшая коллекция больших файлов для жестких ссылок.

Предостережение к этому типу сценария использования заключается в том, что в файловых системах, использующих COW, изменение «оригинала» может сломать жесткие ссылки, но не сломать программные ссылки. Но если целью является получение мастер-копии после редактирования, сохранения и сортировки, COW не входит в сценарий.


3
К вашему сведению: снимки btrfs не являются жесткими ссылками. Они имеют различное поведение (например, изменение одной копии не изменяет другую). И statпокажет только одну ссылку.
Дероберт

@derobert Не уверен, как работают снимки, небольшое исследование показывает интересные вещи. Для неизмененных файлов / каталогов statпоказывают тот же номер инода, но другой идентификатор устройства. Должно быть связано с тем, как субтомы накладываются на основной, редко монтируемый том. Я подозреваю, что, если основной том был смонтирован stat, показывалось бы количество ссылок, равное количеству снимков, на которых размещалась эта версия файла. COW, вероятно, позаботится о модификации, не затрагивая другие. Простое предположение, основанное на умеренном любопытстве, но недостаточно любопытное, чтобы копать глубже.
Цыганка

Каждая символическая ссылка имеет свой собственный inode, поэтому она использует запись inode в файловой системе. Традиционные файловые системы Unix требуют, чтобы вы выбирали, сколько места резервировать для inode во время создания FS, вместо того, чтобы выделять его по мере необходимости, как это делает XFS. Таким образом, на самом деле важно, что версия символической ссылки использовала бы намного больше инодов (даже помимо последствий для кэша VFS).
Питер Кордес

23

Жесткие ссылки полезны в тех случаях, когда вы не хотите связывать существование обоих файлов. Учти это:

touch a
ln -s a b
rm a

Теперь bбесполезно. (И эти шаги могут происходить довольно далеко друг от друга, быть выполнены разными людьми и т. Д.)

Принимая во внимание, что с жесткой ссылкой,

touch a
ln a b
rm a

b все еще присутствует и правильно.


8
@MatthewCline. Такое поведение требуется при управлении эффективными инкрементными резервными копиями. Особенно, когда старые резервные копии удаляются, в системе резервного копирования на основе мягких ссылок вам придется проверять и повторно связывать все новые резервные файлы / ссылки с действительной базой, в то время как жесткие ссылки выполняют эту работу "бесплатно" на уровне inode. например, timehift / backintime широко использует жесткие ссылки.
orzechow

3
@orzechow Я не думаю, что вам нужно поведение жестких ссылок где-нибудь рядом с вашей резервной системой. github.com/bit-team/backintime/wiki/… backintime глупо полагает, что все изменения в файлах будут выполняться с помощью цикла удаления-создания, а не обновления на месте.
ДепрессияДаниэль

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

1
Это не ответ - в частности, это не случай использования. Это просто демонстрация поведения жестких ссылок.
user394

1
@ ThomasPadron-McCarthy, это недоразумение. BiT использует жесткие ссылки только для связи идентичных файлов в разных снимках. Они НЕ связаны с оригинальным файлом! (Я BiT Dev)
Germar

11

Отдельная программа может изменить свое поведение в зависимости от того, под каким именем она запускается:

$ ls -li `which pgrep` `which pkill`
208330 -r-xr-xr-x  2 root  bin  19144 Jul 26  2016 /usr/bin/pgrep
208330 -r-xr-xr-x  2 root  bin  19144 Jul 26  2016 /usr/bin/pkill

Который в источнике определяется через что-то вроде

if (strcmp(__progname, "pgrep") == 0) {
    action = grepact;
    pgrep = 1;
} else {
    action = killact;

хотя точные детали будут варьироваться в зависимости от операционной системы и языка.

Это позволяет (в основном) идентичный код не компилироваться в два (в основном) идентичных двоичных файла. Имейте в виду, что Unix датирует дни, когда дисковое пространство было очень дорогим, хотя, согласно Стивенсу в главе 4 APUE, символические ссылки были реализованы в BSD4.2 (1983), чтобы заменить различные ограничения жестких ссылок. Тестовая программа, проверяющая, используется ли имя символической ссылки в качестве имени программы, может выглядеть примерно так:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    printf("called as '%s'\n", *argv);
    exit(0);
}

И проверено через:

$ cc -o myname myname.c 
$ ln -s myname alias
$ ./myname
called as './myname'
$ ./alias
called as './alias'
$ 

4
Но разве это обычно не обрабатывается с помощью мягких ссылок?
Мэтью Клайн

1
@ MatthewCline это могло бы быть сегодня, но символические ссылки не существовали до 4.2BSD (1983), согласно Стивенсу в APUE.
thrig

4
@ thrig, вопрос, в частности, требует вариантов использования, которые не могут быть выполнены с помощью символических ссылок или, по крайней мере, предпочтительнее, чем использование символических ссылок. Ваш ответ применим как к HL, так и к SL.
Марсело

3
BusyBox принимает это к максимуму.
Макс

8

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

Преимущества:

  • Я по-прежнему делюсь файлом в сети P2P, как и должен, даже если я rmили mv«копия».
  • Файл также находится по пути, где мне это нужно; большинство таких мест не являются общими.
  • Я могу rm«оригинал» прекратить делиться файлом; эта операция не влияет на «копирование» в нужном месте.
  • Мое дисковое пространство используется только один раз.

Суть в том, что если бы я заранее знал, какой файл мне нужен rm, я мог бы использовать символическую ссылку. Но я никогда не знаю.


6

Файловые системы - это простой и в то же время эффективный способ организации и классификации файлов (это их основная причина существования). Жесткие ссылки обеспечивают более высокую степень гибкости в этом вопросе.

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

Итак, здесь есть некоторые варианты использования, которые посещают жесткие ссылки, но не мягкие ссылки :

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

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

  3. Другая очень важная, но редко упоминаемая причина существования жестких ссылок - это ..подкаталоги. Эти ..каталоги на самом деле (в большинстве Unix фс реализации) жесткие ссылки на родительский каталог, без жестких ссылок это должно быть реализовано в совершенно по- другому, в то время как наличие жестких ссылок делает это очень легко реализовать.


1
Что касается пункта 1, использование uuids в качестве «канонического» имени для файлов и превращение всех понятных человеку имен в символические ссылки на uuids является альтернативным решением.
R ..

Хотя предложение uuids звучит академически правильно, использование uuids для имен файлов не очень практично, и опять же, цель состоит в том, чтобы упростить вещи, а не сделать их более сложными или «менее понятными для человека». Кроме того, наличие uudis для «канонической» ссылки на файл было бы просто дополнительным косвенным указанием на фактический файловый индекс, поэтому нет смысла достигать этого подхода, поскольку он не дает никаких преимуществ, а только таких недостатков, как: влияние на производительность, дополнительные дисковое пространство для хранения большего количества записей каталога, с кучей файлов со «странными» именами вокруг ...
Marcelo

5

Очень распространенный пример из реальной жизни, требующий жестких ссылок:

git clone --reference <repository>

Это клоны из локального репозитория Git с почти нулевым копированием. Вместо копирования объектных файлов (неизменяемых файлов, используемых Git для своей «базы данных»), он просто жестко связывает их.

Любое хранилище может удалить объект, но индекс остается действительным для остальных хранилищ. И если объект удаляется из всех репозиториев, он удаляется с диска. Жесткие ссылки создают прекрасное и быстрое решение. Очень часто встречается на CI-серверах.


Существует версия , не жестко ссылка: git clone --shared <repository>. Это, однако, непостоянно и имеет много предостережений, поскольку все работают над одним и тем же каталогом.


4

Недавно у меня был сценарий использования несколько безопасной процедуры обновления для систем на основе U-Boot, где uImageесть программная ссылка, указывающая на образ для загрузки, идея заключалась в том, что отключение питания не должно создавать проблем, независимо от того, в какой момент обработать это происходит (при условии, что файловая система играет вместе):

ln image.bin backup_image.bin
ln -sf backup_image.bin uImage

// replace image.bin

ln -sf image.bin uImage
rm backup_image.bin

Без жестких ссылок это было бы не так просто.

/редактировать:

Благодаря комментариям теперь я знаю, что было бы лучше сделать:

ln image.bin backup_image.bin
ln -sf backup_image.bin uImageNew
mv uImageNew uImage || rm -rf uImage && mv uImageNew uImage

// replace image.bin

ln -sf image.bin uImageNew
mv uImageNew uImage || rm -rf uImage && mv uImageNew uImage
rm backup_image.bin

(Это rmздесь для того, чтобы можно было лучше избежать странного состояния, например, если uImageесть что-то неожиданное, что может привести к mvсбою [но не обязательно к предыдущему ln -sfрешению].)


2
+1 потому что это концептуально очень хорошая причина, но, к сожалению ln -sf, не атомарная. Удаляет старую символическую ссылку и создает новую. Чтобы это исправить, вам нужно создать новую символическую ссылку с временным именем и rename(2)( mv) на имя того, который вы хотите заменить.
Р.

@R .. Ты прав! Ph stat("uImage", {st_mode=S_IFREG|0777, st_size=0, ...}) unlink("uImage"),symlink("backup_image.bin", "uImage")
phk

1
Кстати, смотрите здесь для моей версии, install.shкоторая решает проблему: git.musl-libc.org/cgit/musl/tree/tools/install.sh
R ..

@R .. Обратите внимание, что mvдаже с -fможет произойти сбой, если место назначения уже существует, например, символическая ссылка, которая является частью цикла символической ссылки. Демо:ln -sf foo bar; ln -sf bar foo; echo "Before:"; ls -l foo bar; >testfile; mv testfile foo || { echo "Using mv -f"; mv -f testfile foo; }; echo "After:"; ls -l foo bar
phk

3

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


3

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

Сначала файлы хранятся в дереве каталогов «пул» на основе их хеша md5. Любая резервная копия, которая использует этот файл, делает жесткую ссылку на файл пула. По истечении срока действия резервных копий / их жесткие ссылки удаляются из файловой системы.

Жесткие ссылки здесь превосходят мягкие ссылки, поскольку они обеспечивают автоматический подсчет ссылок. Задание cron периодически удаляет все файлы в каталоге пула, которые не имеют более одной ссылки.

Этот метод имеет некоторые недостатки (в основном, из-за того, что для репликации хранилища резервных копий сложно использовать инструменты на основе файловой системы), но на практике он оказался достаточно надежным.


Другой вариант использования: сервер веб-приложений Java tomcat обрабатывает имена файлов как метаданные. Файл Java «войны» должен быть назван в зависимости от его пути на веб-сервере.

Например: foo.war это код Java, который обслуживает URL/foo

К сожалению, он разрешает символические ссылки до принятия этого решения.

Итак, скажем, вы хотите развернуть сборку приложения и дать ему описательное имя файла (например, с номером выпуска или датой). Вы не можете сделать символическую ссылку на файл с «настоящим» именем - вы должны сделать жесткую ссылку.

foo.warсимволическая ссылка foo-20170129.warне работает

foo.warжестко связан с foo-20170129.warработами.

Мне не нравится это поведение кота, но жесткие ссылки дают мне возможность обойти это.

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