я бегу
ln /a/A /b/B
Я хотел бы видеть в папке, a
где файл A указывает на ls
.
linux
filesystems
hardlink
Лео Леопольд Герц 준영
источник
источник
link(2)
системного вызова не имеет смысла, кто является оригиналом, а кто - ссылкой. Вот почему, как показывают ответы, единственный способ найти все ссылкиfind / -samefile /a/A
. Потому что одна запись каталога для inode не «знает» о других записях каталога для того же inode. Все, что они делают, это пересчитывают индекс, чтобы он мог быть удален, когда фамилия для негоunlink(2)ed
. (Это «количество ссылок» вls
выходных данных).Ответы:
Вы можете найти номер инода для вашего файла с помощью
а также
показывает количество ссылок (количество жестких ссылок на определенный индекс)
после того как вы нашли номер инода, вы можете искать все файлы с одинаковым инодом:
покажет имена файлов для inode NUM в текущем каталоге (.)
источник
На самом деле нет четко определенного ответа на ваш вопрос. В отличие от символических ссылок, жесткие ссылки неотличимы от «оригинального файла».
Записи каталога состоят из имени файла и указателя на индекс. Индод, в свою очередь, содержит метаданные файла и (указатели на) фактическое содержимое файла). Создание жесткой ссылки создает другое имя файла + ссылку на тот же индекс. Эти ссылки являются однонаправленными (по крайней мере, в типичных файловых системах) - индекс хранит только счетчик ссылок. Не существует внутреннего способа узнать, какое имя файла является «оригинальным».
Кстати, именно поэтому системный вызов «удалить» файл называется
unlink
. Это просто удаляет жесткую ссылку. Индод, к которому прикреплены данные, удаляется только в том случае, если счетчик ссылок инода падает до 0.Единственный способ найти другие ссылки на данный индекс - это провести тщательный поиск в файловой системе, проверяя, какие файлы ссылаются на рассматриваемый индекс. Вы можете использовать 'test A -ef B' из оболочки для выполнения этой проверки.
источник
UNIX имеет жесткие ссылки и символические ссылки (сделаны с
"ln"
и"ln -s"
соответственно). Символические ссылки - это просто файл, который содержит реальный путь к другому файлу и может пересекать файловые системы.Жесткие ссылки существуют с самых первых дней существования UNIX (я все равно помню, и это довольно давно). Это две записи каталога , которые ссылаются на точные же данные. Данные в файле определяются его
inode
. Каждый файл в файловой системе указывает на индекс, но нет требования, чтобы каждый файл указывал на уникальный индекс - отсюда и жесткие ссылки.Поскольку inode уникальны только для данной файловой системы, существует ограничение, что жесткие ссылки должны быть в одной файловой системе (в отличие от символических ссылок). Обратите внимание, что в отличие от символьных ссылок, нет привилегированного файла - все они равны. Область данных будет освобождена только тогда, когда все файлы, использующие этот индекс, будут удалены (и все процессы также закроют ее, но это другая проблема).
Вы можете использовать
"ls -i"
команду, чтобы получить индекс определенного файла. Затем вы можете использовать"find <filesystemroot> -inum <inode>"
команду, чтобы найти все файлы в файловой системе с указанным индексом.Вот скрипт, который делает именно это. Вы вызываете это с помощью:
и он найдет все файлы в этой файловой системе, которые являются жесткими ссылками для этого файла:
Вот сценарий.
источник
. ./findhardlinks.bash
находясь в OS X Zsh. Мое текущее окно на экране закрывается.INUM=$(stat -c %i $1)
. ТакжеNUM_LINKS=$(stat -c %h $1)
. См.man stat
Больше переменных формата, которые вы можете использовать.Первый столбец будет представлять разрешения. Во втором столбце будет указано количество подпунктов (для каталогов) или количество путей к тем же данным (жесткие ссылки, включая исходный файл) к файлу. Например:
источник
inode
что в свою очередь указывает на содержимое диска.Как насчет следующего более простого? (Последние могут заменить длинные сценарии выше!)
Если у вас есть конкретный файл
<THEFILENAME>
и вы хотите знать все его жесткие ссылки, распределенные по каталогу<TARGETDIR>
(который может быть даже обозначен всей файловой системой/
)Расширяя логику, если вы хотите знать все файлы в
<SOURCEDIR>
нескольких жестких ссылках<TARGETDIR>
:источник
-type f
потому что файл тоже может быть каталогом..
И..
записи в каталогах жесткие ссылки. Вы можете определить, сколько подкаталогов находится в каталоге, по количеству ссылок.
. В любом случае это спорный вопрос, так какfind -samefile .
все равно не будет выводитьsubdir/..
вывод.find
(по крайней мере, версия GNU) кажется жестко закодированным, чтобы игнорировать..
, даже с-noleaf
.O(n^2)
и выполняетсяfind
один раз для каждого члена набора жестко связанных файлов.find ... -printf '%16i %p\n' | sort -n | uniq -w 16 --all-repeated=separate
будет работать (16 недостаточно для десятичного представления 2 ^ 63-1, поэтому, когда ваша файловая система XFS достаточно велика, чтобы иметь столь высокие номера инодов, будьте внимательны)Есть много ответов со скриптами, чтобы найти все жесткие ссылки в файловой системе. Большинство из них делают глупые вещи, такие как запуск find для сканирования всей файловой системы на
-samefile
предмет КАЖДОГО многосвязного файла. Это безумие; все, что вам нужно, это отсортировать по номеру инода и распечатать дубликаты.Только один проход по файловой системе, чтобы найти и сгруппировать все наборы жестко связанных файлов
Это намного быстрее, чем другие ответы для поиска нескольких наборов жестко связанных файлов.
find /foo -samefile /bar
отлично подходит только для одного файла.-xdev
: ограничение на одну файловую систему. Строго не требуется, так как мы также печатаем идентификатор FS в uniq на! -type d
отклонять каталоги:.
и..
запись означает , что они всегда связаны между собой .-links +1
: количество ссылок строго> 1
-printf ...
выведите FS-id, номер индекса и путь. (С дополнением к фиксированной ширине столбца, о котором мы можем рассказатьuniq
.)sort -n | uniq ...
числовая сортировка и унификация по первым 42 столбцам, разделяя группы пустой строкойИспользование
! -type d -links +1
означает, что входные данные сортировки настолько же велики, как и конечные выходные данные uniq, поэтому мы не занимаемся огромной сортировкой строк. Если вы не запустите его в подкаталоге, который содержит только один из набора жестких ссылок. В любом случае, для повторного обхода файловой системы потребуется гораздо меньше процессорного времени, чем для любого другого опубликованного решения.образец вывода:
TODO ?: распаковать вывод с помощью
awk
илиcut
.uniq
имеет очень ограниченную поддержку выбора полей, поэтому я дополняю результаты поиска и использую фиксированную ширину. 20 символов достаточно широки для максимально возможного индекса или номера устройства (2 ^ 64-1 = 18446744073709551615). XFS выбирает номера инодов в зависимости от того, где на диске они расположены, а не от 0, поэтому большие файловые системы XFS могут иметь> 32-битные номера инодов, даже если у них нет миллиардов файлов. Другие файловые системы могут иметь 20-значные номера инодов, даже если они не гигантские.TODO: сортировка групп дубликатов по пути. Сортировка их по точке монтирования, а затем по номеру инода смешивает вещи, если у вас есть пара разных подкаталогов, которые имеют много жестких ссылок. (то есть группы дуп-групп объединяются, но вывод смешивает их).
Финал
sort -k 3
сортирует строки отдельно, а не группы строк как одну запись. Предварительная обработка чего-либо для преобразования пары новых строк в байт NUL и использование GNUsort --zero-terminated -k 3
могут помочь.tr
работает только с одиночными символами, но не с 2-> 1 или 1-> 2 шаблонами.perl
будет делать это (или просто разобрать и отсортировать в perl или awk).sed
может также сработать.источник
%D
идентификатор файловой системы (она является уникальным для текущей загрузки , а не файловые системы неumount
эд), поэтому следующий еще более общий характер :find directories.. -xdev ! -type d -links +1 -printf '%20i %20D %p\n' | sort -n | uniq -w 42 --all-repeated=separate
. Это работает до тех пор, пока ни один каталог не содержит другой каталог на уровне файловой системы, а также он смотрит на все, что может быть жестко связано (например, устройства или программные ссылки - да, программные ссылки могут иметь количество ссылок больше 1). Обратите внимание, чтоdev_t
и сегодняino_t
это 64 бит. Это, вероятно, будет продолжаться до тех пор, пока у нас есть 64-битные системы.! -type d
вместо-type f
. У меня даже есть жесткие ссылки в моей файловой системе для организации некоторых коллекций файлов. Обновил мой ответ с вашей улучшенной версией (но я сначала поставил fs-id, так что порядок сортировки по крайней мере группируется по файловой системе.)Это своего рода комментарий к собственному ответу и сценарию Торокоро-Мачо, но он явно не помещается в поле для комментариев.
Переписал ваш сценарий, используя более простые способы поиска информации и, таким образом, значительно меньше вызовов процессов.
Я старался сделать его максимально похожим на ваш, чтобы его можно было легко сравнить.
Комментарии к этому и вашему сценарию
Следует всегда избегать
$IFS
магии, если достаточно глобуса, поскольку он излишне запутан, а имена файлов на самом деле могут содержать символы новой строки (но на практике в основном это первая причина).Вы должны избегать ручного разбора
ls
и такого вывода в максимально возможной степени, так как это рано или поздно укусит вас. Например: в первойawk
строке вы ошибаетесь во всех именах файлов, содержащих пробелы.printf
в конце концов, часто избавляет от неприятностей, так как он очень устойчив с%s
синтаксисом. Он также дает вам полный контроль над выходом и в отличие от всех системecho
.stat
может сэкономить вам много логики в этом случае.GNU find
это мощныйВаши вызовы
head
иtail
вызовы могли быть обработаны напрямую,awk
например, с помощьюexit
команды и / или выбораNR
переменной. Это сохранит вызовы процессов, что почти всегда значительно повышает производительность в трудолюбивых сценариях.Ваши
egrep
с тем же успехом могут быть простоgrep
.источник
find ... -xdev -type f -links +1 -printf '%16i %p\n' | sort -n | uniq -w 16 --all-repeated=separate
. Это НАМНОГО быстрее, так как проходит только один раз. Для нескольких FS, вам нужно префикс номера Inode с идентификатором FS. Возможно сfind -exec stat... -printf ...
Основываясь на
findhardlinks
сценарии (переименовал егоhard-links
), это то, что я реорганизовал и заставил его работать.Выход:
источник
Решение с графическим интерфейсом действительно близко к вашему вопросу:
Вы не можете перечислить фактические жестко связанные файлы из «ls», потому что, как указывали предыдущие комментаторы, «имена» файлов являются просто псевдонимами к тем же данным. Тем не менее, на самом деле есть инструмент с графическим интерфейсом, который очень близок к тому, что вы хотите, который отображает список путей имен файлов, которые указывают на те же данные (как жесткие ссылки) в Linux, он называется FSLint. Требуемая опция находится в разделе «Конфликты имен» -> снимите флажок «$ PATH» в разделе «Поиск (XX) ->» и выберите «Псевдонимы» в раскрывающемся списке после «для ...» по направлению к верхней середине.
FSLint очень плохо документирован, но я обнаружил, что удостоверился, что ограниченное дерево каталогов в разделе «Путь поиска» с установленным флажком «Recurse?» и вышеупомянутые опции, список жестко связанных данных с путями и именами, которые «указывают» на одни и те же данные, создаются после поиска программы.
источник
Вы можете настроить
ls
выделение жестких ссылок с помощью «псевдонима», но, как было сказано ранее, нет способа показать «источник» жесткой ссылки, поэтому я добавляю,.hardlink
чтобы помочь с этим.Добавьте следующее где-то в вашем
.bashrc
источник