Come posso trovare tutti i file hardlinked su un filesystem?


21

Devo trovare tutti i file con collegamento fisico su un determinato filesystem. Ad esempio ottenere un elenco di file, ogni riga contiene coppie collegate o terzine, ecc.

Capisco più o meno come farlo, è necessario creare un dizionario codificato dall'inode per tutti i file / directory su un filesystem, escludere "." e ".." link, e quindi gli indode con più di un nome sono hardlink ... Ma spero che esista forse una soluzione già pronta, o che qualcuno abbia già scritto un tale script.

Risposte:


17

È possibile eseguire il comando seguente:

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

per trovare tutti i file hard link.

O versione @mbafford:

find / -type f -links +1 -printf '%i %n %p\n'

1
Grazie, questo non è esattamente quello che volevo, ma abbastanza vicino. Posso aggiungere '% i' per stampare i numeri di inode e quindi ordinare / raggruppare per esso ...
— haimg

15
Puoi evitare la necessità di awk usando "-link + n 'sintassi di find, ad es. Per trovare tutti i file con almeno due link e stampare le informazioni necessarie:find / -type f -links +1 -printf '%i %n %p\n'
— mbafford,

che ne dite di passare attraverso sort(+ uniq)? ero curioso, quindi ho provato il mio computer principale (16 GB i5-2500k con SSD). con 2187757 file ( find / -xdev -type f | wc) richiede 12 secondi reali quando si restituiscono 3820 file / 570 inode ( time sudo find / -xdev -type f -links +1 -printf "%i\n" | sort | uniq | wc). dovresti includere il %n %pper i file effettivi come li ho estratti per il conteggio degli inode.
— Northern-Bradley,

17
find . -type f -links +1 2>/dev/null

fornisce un elenco di tutti i file che hanno più di un collegamento, ovvero file a cui esiste un collegamento reale. Eseguire il ciclo su questo è quindi relativamente semplice: una soluzione caotica se non si dispone di così tanti file

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

Spero sinceramente che ci siano soluzioni migliori, ad esempio lasciando che la prima findchiamata stampi i numeri degli inode e quindi usando l find' -inumopzione per mostrare tutti i file associati a questo inode.


1
Ahia! Questo analizza il filesystem ancora e ancora per ogni file hardlinked ...
— haim

1
Non ho affermato che fosse veloce - e in qualche modo funziona per piccoli alberi di directory. Naturalmente, un indice adeguato, che potrebbe essere creato, ad esempio, dall'output di find . -type f -printf '%i %p\n', consentirebbe di costruire una soluzione molto più veloce.
— Claudio,

E questo non gestisce lo spazio nel percorso AFAIK.
— Gilles Quenot,

Per il forloop, regolare IFS di conseguenza funzionerebbe. Per analizzare l'output del comando find nel mio commento, dichiarare che tutto il nome tra il primo spazio e la fine della riga dovrebbe essere anche il nome del file.
— Claudio,

1
@Sati: assicura che i messaggi di errore vengano scartati (ad es. Per le cartelle a cui non hai accesso, lost+foundecc.); che è particolarmente importante, se l'output deve essere ulteriormente elaborato come nella seconda riga.
— DJCrashdummy,

1

IMHO il modo migliore è usare la seguente riga (di sicuro devi sostituire /PATH/FOR/SEARCH/con quello che vuoi cercare):

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

questo esegue la scansione del filesystem una sola volta, mostra l'inode, il numero di hardlink e il percorso dei file con più di un hardlink e li ordina in base all'inode.

se sei infastidito dai messaggi di errore per le cartelle che non sei autorizzato a leggere, puoi espandere la riga in questo modo:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.