Existem muitas respostas com scripts para encontrar todos os hardlinks em um sistema de arquivos. A maioria faz coisas bobas como executar find para varrer todo o sistema de arquivos por -samefile
para CADA arquivo com múltiplas conexões. Isso é loucura; tudo que você precisa é classificar o número de inode e imprimir duplicatas.
find directories.. -xdev ! -type d -links +1 -printf '%20D %20i %p\n' | sort -n | uniq -w 42 --all-repeated=separate
(Obrigado ao @Tino por ajustar meu comando original para suportar um FS-id ( %D
), e para lidar com todos os tipos de arquivos não-diretórios, não apenas com arquivos regulares. links simbólicos, canais, etc.)
Usar ! -type d -links +1
significa que a entrada desse tipo é tão grande quanto a saída final do uniq. A menos que você o execute em um subdiretório que contenha apenas um conjunto de hardlinks. De qualquer forma, isso usará muito menos tempo de CPU para reencaminhar o sistema de arquivos do que qualquer outra solução publicada.
exemplo de saída:
...
2429 76732484 /home/peter/weird-filenames/test/.hiddendir/foo bar
2429 76732484 /home/peter/weird-filenames/test.orig/.hiddendir/foo bar
2430 17961006 /usr/bin/pkg-config.real
2430 17961006 /usr/bin/x86_64-pc-linux-gnu-pkg-config
2430 36646920 /usr/lib/i386-linux-gnu/dri/i915_dri.so
2430 36646920 /usr/lib/i386-linux-gnu/dri/i965_dri.so
2430 36646920 /usr/lib/i386-linux-gnu/dri/nouveau_vieux_dri.so
2430 36646920 /usr/lib/i386-linux-gnu/dri/r200_dri.so
2430 36646920 /usr/lib/i386-linux-gnu/dri/radeon_dri.so
...
TODO ?: des-preenche a saída. uniq
tem suporte de seleção de campo muito limitado, portanto, preenho a saída de localização e uso de largura fixa. 20chars é grande o suficiente para o máximo possível inode ou número do dispositivo (2 ^ 64-1 = 18446744073709551615). O XFS escolhe os números de inode com base no local em que eles estão alocados, não contiguamente a partir de 0, portanto, sistemas de arquivos XFS grandes podem ter números de inótipos de > 32 bits, mesmo que não tenham bilhões de arquivos. Outros sistemas de arquivos podem ter números de inodes de 20 dígitos, mesmo que não sejam gigantescos.
TODO: classifica grupos de duplicatas por caminho. Tendo eles classificados por ponto de montagem, o número de inode mistura as coisas juntas, se você tiver um par de subdiretórios diferentes que tenham muitos hardlinks. (isto é, grupos de grupos dup vão juntos, mas a saída os mistura).
Um sort -k 3
final classificaria as linhas separadamente, não grupos de linhas como um único registro. O pré-processamento com algo para transformar um par de novas linhas em um byte NUL e o uso do GNU sort --zero-terminated -k 3
pode ajudar. O tr
só opera em caracteres únicos, não em padrões 2 > 1 ou 1 > 2. perl
iria fazer isso (ou apenas analisar e ordenar dentro de perl ou awk). sed
também pode funcionar.