Как я могу найти все жестко связанные файлы в файловой системе?

21

Мне нужно найти все жестко связанные файлы в данной файловой системе. Например, получить список файлов, каждая строка содержит связанные пары или триплеты и т. Д.

Я более или менее понимаю, как это сделать, нужно создать словарь с ключом inode для всех файлов / каталогов в файловой системе, исключив "." и ссылки "..", а затем индоды с более чем одним именем являются жесткими ссылками ... Но я надеюсь, что, возможно, существует готовое решение или кто-то уже написал такой сценарий.

haimg
источник

Ответы:

17

Вы можете запустить следующую команду:

find / -type f -printf '%n %p\n' | awk '$1 > 1{$1="";print}'

найти все жестко связанные файлы.

Или версия @mbafford:

find / -type f -links +1 -printf '%i %n %p\n'
Жиль Квено
источник
1
Спасибо, это не совсем то, что я хотел, но достаточно близко. Я могу добавить «% i», чтобы напечатать номера
инодов,
15
Вы можете избежать необходимости использовать awk, используя синтаксис find "-links + n ', например, чтобы найти все файлы, содержащие не менее двух ссылок, и распечатать необходимую информацию:find / -type f -links +1 -printf '%i %n %p\n'
mbafford
как насчет прокачки sort(+ uniq)? Мне было любопытно, поэтому я попробовал его на своем главном компьютере (16GB i5-2500k с ssd). с 2187757 файлами ( find / -xdev -type f | wc) занимает 12 реальных секунд при возврате 3820 файлов / 570 inode ( time sudo find / -xdev -type f -links +1 -printf "%i\n" | sort | uniq | wc). вам нужно будет включить %n %pдля фактических файлов, как я вынул их для подсчета inode.
Северный Брэдли
17
find . -type f -links +1 2>/dev/null

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

for i in $(find . -type f -links +1 2>/dev/null); do find -samefile $i | awk '{printf "%s ", $1}'; printf "\n"; done | sort | uniq

Но я искренне надеюсь , что есть более эффективные решения, например, позволяя первые findномера печати инодов вызовов , а затем с помощью find«s -inumвозможности показать все файлы , связанные с этим инодом.

Клавдий
источник
1
Ой! Это сканирует файловую систему снова и снова для каждого файла с
жесткими ссылками
1
Я не утверждал, что это быстро - и это вроде работает для небольших деревьев каталогов. Конечно, правильный индекс, который можно построить, например, на основе результатов find . -type f -printf '%i %p\n', позволил бы создать гораздо более быстрое решение.
Клавдий
И это не обрабатывать пространство в пути AFAIK.
Жиль Квено
Для forцикла, настройка IFS соответственно будет работать. Чтобы проанализировать вывод команды find в моем комментарии, также должно работать объявление всего между первым пробелом и концом строки как имени файла.
Клавдий
1
@Sati: он гарантирует, что сообщения об ошибках отбрасываются (например, для папок, к которым у вас нет доступа и lost+foundт. Д.); что особенно важно, если вывод должен обрабатываться дальше, как во второй строке.
DJCrashdummy
1

ИМХО, лучше всего использовать следующую строку (наверняка вам придется заменить /PATH/FOR/SEARCH/на то, что вы хотите найти):

find /PATH/FOR/SEARCH/ -xdev -printf '%i\t%n\t%p\n' | fgrep -f <(find . -xdev -printf '%i\n' | sort -n | uniq -d) | sort -n

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

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

find /PATH/FOR/SEARCH/ -xdev -printf '%i\t%n\t%p\n' 2> /dev/null | fgrep -f <(find . -xdev -printf '%i\n' 2> /dev/null | sort -n | uniq -d) | sort -n
DJCrashdummy
источник