Bagaimana saya bisa menemukan semua file yang di-hardlink pada sistem file?


21

Saya perlu menemukan semua file yang di-hardlink pada sistem file yang diberikan. Misalnya mendapatkan daftar file, setiap baris berisi pasangan yang terhubung, atau kembar tiga, dll.

Saya mengerti kurang lebih bagaimana melakukannya, kita perlu membuat kamus yang dikunci oleh inode untuk semua file / direktori pada sistem file, kecuali "." dan tautan "..", dan kemudian indode dengan lebih dari satu nama adalah hardlink ... Tapi saya harap mungkin ada solusi yang sudah ada, atau seseorang sudah menulis skrip seperti itu.

Jawaban:


17

Anda dapat menjalankan perintah berikut:

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

untuk menemukan semua file yang ditautkan dengan keras.

Atau versi @mbafford:

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

1
Terima kasih, ini bukan yang saya inginkan, tetapi cukup dekat. Saya dapat menambahkan '% i' untuk mencetak nomor inode dan kemudian mengurutkan / mengelompokkannya ...
haimg

15
Anda dapat menghindari kebutuhan awk dengan menggunakan sintaks "-links + n 'find. Mis. Untuk menemukan semua file dengan setidaknya dua tautan dan mencetak info yang diperlukan:find / -type f -links +1 -printf '%i %n %p\n'
mbafford

bagaimana dengan piping melalui sort(+ uniq)? Saya penasaran jadi mencobanya di komputer utama saya (16GB i5-2500k dengan SSD). dengan 2187757 file ( find / -xdev -type f | wc) membutuhkan 12 detik nyata saat mengembalikan 3820 file / 570 inode ( time sudo find / -xdev -type f -links +1 -printf "%i\n" | sort | uniq | wc). Anda harus memasukkan %n %puntuk file yang sebenarnya karena saya mengambilnya untuk menghitung inode.
north-bradley

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

memberikan daftar semua file yang memiliki lebih dari satu tautan, yaitu file yang terdapat tautan keras. Melompati hal ini relatif mudah - solusi peretasan jika Anda tidak memiliki banyak 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

Tapi saya sangat berharap bahwa ada solusi yang lebih baik, misalnya dengan membiarkan pertama findpanggilan nomor cetak inode dan kemudian menggunakan find's -inumpilihan untuk menampilkan semua file yang terkait dengan inode ini.


1
Aduh! Ini memindai sistem file berulang-ulang untuk setiap file yang di-hardlink ...
haimg

1
Saya tidak mengklaim itu cepat - dan itu semacam bekerja untuk pohon direktori kecil. Tentu saja, indeks yang tepat, yang dapat dibangun dari, misalnya, output dari find . -type f -printf '%i %p\n', akan memungkinkan seseorang untuk membangun solusi yang jauh lebih cepat.
Claudius

Dan itu tidak menangani ruang di jalur AFAIK.
Gilles Quenot

Untuk forloop, menyesuaikan IFS sesuai akan berhasil. Untuk mem-parsing output dari perintah find dalam komentar saya, menyatakan semuanya antara spasi pertama dan akhir baris sebagai nama file harus bekerja juga.
Claudius

1
@Sati: memastikan bahwa pesan kesalahan dibuang (mis. Untuk folder yang tidak Anda sukai, lost+founddll.); yang sangat penting, jika output harus diproses lebih lanjut seperti pada baris kedua.
DJCrashdummy

1

IMHO cara terbaik adalah dengan menggunakan baris berikut (pasti Anda harus mengganti /PATH/FOR/SEARCH/dengan apa pun yang ingin Anda cari):

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

ini memindai sistem file hanya sekali, menunjukkan inode, jumlah hardlink dan jalur file dengan lebih dari satu hardlink dan mengurutkannya sesuai dengan inode.

jika Anda terganggu oleh pesan kesalahan untuk folder yang Anda tidak boleh baca, Anda dapat memperluas baris ke ini:

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.