Bash

列印帶有硬連結數量的文件

  • May 3, 2016

我可以通過使用列印目錄中文件的硬連結數量,find . type f -printf "%f %n\n" 但這也會列印硬連結,而不僅僅是原始文件:

範例:file1 是原始文件。hardlink1 是指向原始 file1 的硬連結。

使用此程式碼它將列印以下內容:

file1 2 hardlink1 2

我希望這個問題只能通過使用來解決find。我只想列印原始文件。

您誤解了硬連結的工作原理。沒有原創。所有文件都只是指向inode的硬連結。因此,硬連結實際上並不連結到文件,而是連結到 inode。

為了說明,考慮這個文件:

$ touch file
$ ls -li file
3282140 -rw-r--r-- 1 terdon terdon 0 May  3 16:27 file

正如您在上面看到的,file指向 inode 3282140。現在,如果我們創建一個指向它的軟連結:

$ ln -s file softlink
$ ls -li 
3282140 -rw-r--r-- 1 terdon terdon 0 May  3 16:27 file
3282141 lrwxrwxrwx 1 terdon terdon 4 May  3 16:29 softlink -> file

軟連結指向file但連結本身(它也是一個文件系統對象,另一個“文件”)具有不同的 inode ( 3282141)。但是,如果我們創建一個硬連結,它將共享相同的 inode:

$ ln file hardlink
$ ls -li
total 0
3282140 -rw-r--r-- 2 terdon terdon 0 May  3 16:27 file
3282140 -rw-r--r-- 2 terdon terdon 0 May  3 16:27 hardlink
3282141 lrwxrwxrwx 1 terdon terdon 4 May  3 16:29 softlink -> file

因此,如果我現在向 中添加一些文本,則與向自身hardlink添加文本完全相同:file

$ echo "foo" > hardlink 
$ cat hardlink 
foo
$ cat file
foo

而且,由於softlink指向file,我將看到fileif I catit 的內容:

$ cat softlink 
foo

如果我將文本添加到 , 也會發生同樣的情況filehardlink並且file是等效的:

$ echo bar >> file
$ cat hardlink 
foo
bar

現在,如果我 delete filesoftlink將是一個斷開的連結,但hardlink不會受到影響:

$ rm file 
$ ls -li
total 4
3282140 -rw-r--r-- 1 terdon terdon 8 May  3 16:33 hardlink
3282141 lrwxrwxrwx 1 terdon terdon 4 May  3 16:29 softlink -> file
$ cat softlink 
cat: softlink: No such file or directory

由於連結的目標已被刪除,因此軟連結已損壞。然而,硬連結仍然存在,因為它指向同一個 inode:

$ cat hardlink 
foo
bar

所有這一切都是說,根本沒有辦法將硬連結與其創建指向的文件區分開來,因為與軟連結不同,它實際上並不是指向文件而創建的。所有文件都是指向文件系統索引節點的硬連結。實際上,刪除文件只是刪除了指向 inode 的連結。它實際上並沒有刪除數據。系統保留指向每個 inode 的連結計數,如果連結計數為 0,則僅考慮可用於寫入的 inode。

您可以做的是找到所有指向 inode 的連結,然後刪除除一個之外的所有連結。如果我們回到最初的位置:

$ rm *
$ touch file
$ ln file hardlink
$ ls -l file hardlink
-rw-r--r-- 2 terdon terdon 0 May  3 16:39 file
-rw-r--r-- 2 terdon terdon 0 May  3 16:39 hardlink
          ^
          |---- the number of links

的輸出ls -l包括指向 inode 的連結數。因此,您可以迭代其輸出(這是解析ls安全的少數情況之一)並刪除連結號 >1 的任何文件:

for file in *; do [ $(ls -l $file | cut -d' ' -f2) -gt 1 ] && rm "$file"; done

只要所有硬連結都在同一個目錄中,這將刪除除一個之外的所有硬連結。

進一步閱讀:http ://teaching.idallen.com/dat2330/04f/notes/links_and_inodes.html

引用自:https://unix.stackexchange.com/questions/280805