Como posso encontrar todos os arquivos vinculados em um sistema de arquivos?

18

Preciso encontrar todos os arquivos vinculados em um determinado sistema de arquivos. Por exemplo, obtenha uma lista de arquivos, cada linha contém pares vinculados, ou trigêmeos, etc.

Entendo mais ou menos como fazê-lo, é necessário criar um dicionário digitado por inode para todos os arquivos / diretórios em um sistema de arquivos, exclua "." e ".." links e, em seguida, códigos com mais de um nome são hardlinks ... Mas espero que exista uma solução pronta ou que alguém já tenha escrito esse script.

haimg
fonte

Respostas:

14

Você pode executar o seguinte comando:

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

para encontrar todos os arquivos vinculados.

Ou versão @mbafford:

find / -type f -links +1 -printf '%i %n %p\n'
Gilles Quenot
fonte
1
Obrigado, isso não é exatamente o que eu queria, mas perto o suficiente. Posso adicionar '% i' para imprimir os números de inode e, em seguida, tipo / grupo por ele ...
haimg
15
Você pode evitar a necessidade do awk usando a sintaxe "-links + n 'do find. Por exemplo, para encontrar todos os arquivos com pelo menos dois links e imprimir as informações necessárias:find / -type f -links +1 -printf '%i %n %p\n'
mbafford
que tal passar por sort(+ uniq)? Fiquei curioso, então tentei no meu computador principal (16GB i5-2500k com ssd). com 2187757 files ( find / -xdev -type f | wc) leva 12 segundos reais ao retornar 3820 arquivos / 570 inodes ( time sudo find / -xdev -type f -links +1 -printf "%i\n" | sort | uniq | wc). você precisaria incluir os %n %parquivos reais, como eu os tirei para contar inodes.
Northern-bradley
15
find . -type f -links +1 2>/dev/null

fornece uma lista de todos os arquivos que possuem mais de um link, ou seja, arquivos para os quais existe um link físico. Fazer um loop sobre isso é relativamente fácil - uma solução hacky, se você não tiver muitos arquivos, seria

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

Mas, sinceramente, espero que haja soluções melhores, por exemplo, permitindo que a primeira findchamada imprima números de inode e, em seguida, use finda -inumopção 's para mostrar todos os arquivos associados a esse inode.

Cláudio
fonte
1
Ai! Isto verifica o sistema de arquivos novo e de novo para cada arquivo hardlinked ...
haimg
Não afirmei que era rápido - e isso funciona para pequenas árvores de diretório. Obviamente, um índice adequado, que poderia ser construído a partir, por exemplo, da saída de find . -type f -printf '%i %p\n', permitiria criar uma solução muito mais rápida.
Claudius
E isso não lida com espaço no caminho AFAIK.
Gilles Quenot
Para o forloop, o ajuste do IFS adequadamente funcionaria. Para analisar a saída do comando find no meu comentário, declarar tudo entre o primeiro espaço e o final da linha como o nome do arquivo também deve funcionar.
Claudius
1
@Sati: garante que as mensagens de erro sejam descartadas (por exemplo, para pastas às quais você não tem acesso, lost+foundetc.); o que é especialmente importante, se a saída for processada como na segunda linha.
DJCrashdummy
0

IMHO, a melhor maneira é usar a seguinte linha (com certeza você deve substituir /PATH/FOR/SEARCH/pelo que deseja pesquisar):

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

isso varre o sistema de arquivos apenas uma vez, mostra o inode, o número de hardlinks e o caminho dos arquivos com mais de um hardlink e os classifica de acordo com o inode.

se você estiver aborrecido com mensagens de erro para pastas que não têm permissão para ler, você pode expandir a linha para isso:

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
fonte