在 GNU/Linux 中刪除硬連結,以及 inode 的故事

4 min

language: ja bn de en es hi ko pt ru zh-cn zh-tw

大家好,我是無能。

很久沒有使用 ln 命令建立連結了,結果不小心忘記刪除 -s 選項,導致建立了硬連結,所以現在要來刪除這些不必要的硬連結。

建立硬連結

執行不帶選項的 ln 命令會建立硬連結。

alleycat:[haturatu]:~/git/hardlink$ ls
alleycat:[haturatu]:~/git/hardlink$ touch hardlink1
alleycat:[haturatu]:~/git/hardlink$ echo "You are an idiot" >> hardlink1 
alleycat:[haturatu]:~/git/hardlink$ cat hardlink1 
You are an idiot
alleycat:[haturatu]:~/git/hardlink$ ls -la
合計 12
drwxr-xr-x   2 haturatu haturatu 4096  1月 12 15:00 .
drwxr-xr-x 114 haturatu haturatu 4096  1月 12 15:00 ..
-rw-r--r--   1 haturatu haturatu   17  1月 12 15:01 hardlink1

我嘗試如上所示建立了一個檔案。

alleycat:[haturatu]:~/git/hardlink$ ln hardlink1 hardlink2
alleycat:[haturatu]:~/git/hardlink$ ls -la
合計 16
drwxr-xr-x   2 haturatu haturatu 4096  1月 12 15:02 .
drwxr-xr-x 114 haturatu haturatu 4096  1月 12 15:00 ..
-rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink1
-rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink2

這樣就建立了一個硬連結。
然後,我們來看看下面的標準輸出。

-rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink1
-rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink2

這個 -rw-r--r-- 2 中的 2 就是硬連結的數量。與建立硬連結之前相比,您可以確認這個值增加了。
而且,這畢竟只是連結,所以不會佔用實際的磁碟空間。它儲存單一資料,inode 號碼相同,指向同一個檔案。
使用 -i 選項確認 inode 號碼。

alleycat:[haturatu]:~/git/hardlink$ ls -lia
合計 16
13238408 drwxr-xr-x   2 haturatu haturatu 4096  1月 12 15:02 .
11406555 drwxr-xr-x 114 haturatu haturatu 4096  1月 12 15:00 ..
13265123 -rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink1
13265123 -rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink2

什麼是 inode?

這畢竟取決於檔案系統,所以上面是在 GNU/Linux 環境下。如果是 BSD 類的檔案系統,可能是 vnode,ZFS 可能是 znode 等,有些許不同,但從歷史上看,可以理解為是原始 UNIX 檔案系統的擴展。

而且,與符號連結不同,硬連結即使刪除 hardlink1hardlink2 仍然存在;即使刪除 hardlink2hardlink1 仍然存在。從這一點來說,似乎可以解釋為檔案系統本身管理著該檔案,但這仍然有點難以理解,對吧?
然而,這樣看來,硬連結很方便,但符號連結可以引用不同磁碟上的檔案,而硬連結不能在不同磁碟上建立。
簡單來說,根據前面的解釋,檔案系統是基於單一磁碟的 inode 基準,所以如果是不同磁碟,則超出該檔案系統的管轄範圍,無法從層次結構上引用。
因此,如果檔案存在於不同磁碟上,就需要建立符號連結。

而且,從檔案系統的角度來看,這在磁碟復原、恢復作業時被廣泛使用,透過參考過去的 inode 資訊來識別哪些 inode 號碼的檔案被建立或刪除。
這裡有一個陷阱:如果檔案被覆寫,這個 inode 號碼也會被更新。這意味著在建立備份腳本等時,可能需要注意建立不會包含覆寫處理的腳本。(我曾經犯過一次錯誤)

識別具有相同 inode 號碼的檔案

可以使用 find 命令進行確認。

alleycat:[haturatu]:~/git/hardlink$ find . -inum 13265123
./hardlink2
./hardlink1

那麼,現在我來刪除 hardlink1

alleycat:[haturatu]:~/git/hardlink$ rm -i hardlink1
rm: 通常檔案 'hardlink1' を削除しますか? y
alleycat:[haturatu]:~/git/hardlink$ ls -lai
合計 12
13238408 drwxr-xr-x   2 haturatu haturatu 4096  1月 12 15:23 .
11406555 drwxr-xr-x 114 haturatu haturatu 4096  1月 12 15:00 ..
13265123 -rw-r--r--   1 haturatu haturatu   17  1月 12 15:01 hardlink2
alleycat:[haturatu]:~/git/hardlink$ cat hardlink2 
You are an idiot

這樣,硬連結的值也變成了 1,並且確認了原本透過 ln hardlink1 hardlink2 建立的 hardlink1 連結,以及擁有與 hardlink1 相同資訊的 hardlink2 存在並包含相同的資料。

實用方面

雖然很久沒碰了,但如果想在同一個磁碟內複製大檔案但又想減少磁碟消耗,似乎使用硬連結會比較好。
嗯,這可能不是經常會刻意使用的東西,但它能讓人稍微了解檔案系統的結構,所以我覺得很有趣。


那麼,下次再見。
請多指教。

Related Posts