為什麼在 UNIX/Linux 中不允許硬連結到目錄?
我在教科書中讀到 Unix/Linux 不允許硬連結到目錄,但允許軟連結。是因為,當我們有循環並且如果我們創建硬連結,並且在一段時間後我們刪除原始文件時,它會指向一些垃圾值?
如果循環是不允許硬連結的唯一原因,那麼為什麼允許指向目錄的軟連結?
這只是一個壞主意,因為沒有辦法區分硬連結和原始名稱之間的區別。
允許到目錄的硬連結會破壞文件系統的有向無環圖結構,可能會創建目錄循環和懸掛目錄子樹,這會使
fsck
任何其他文件樹遍歷器容易出錯。首先,要理解這一點,我們來談談 inode。文件系統中的數據保存在磁碟上的塊中,這些塊由 inode 收集在一起。您可以將 inode 視為文件。但是,inode 缺少文件名。這就是連結的來源。
連結只是指向 inode 的指針。目錄是保存連結的 inode。目錄中的每個文件名只是一個指向 inode 的連結。在 Unix 中打開文件也會創建一個連結,但它是一種不同類型的連結(它不是命名連結)。
硬連結只是指向該 inode 的額外目錄條目。當你
ls -l
,權限後的數字是命名的連結計數。大多數正常文件都有一個連結。為文件創建新的硬連結將使兩個文件名指向同一個 inode。筆記:% ls -l test ls: test: No such file or directory % touch test % ls -l test -rw-r--r-- 1 danny staff 0 Oct 13 17:58 test % ln test test2 % ls -l test* -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 % touch test3 % ls -l test* -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 -rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3 ^ ^ this is the link count
現在,您可以清楚地看到沒有硬連結之類的東西。硬連結與正常名稱相同。在上面的例子中,
test
或者test2
,哪個是原始文件,哪個是硬連結?到最後,您無法真正分辨(即使通過時間戳),因為兩個名稱都指向相同的內容,相同的 inode:% ls -li test* 14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test 14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 14445892 -rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3
-i
標誌在行的開頭向您ls
顯示 inode 編號。請注意如何test
和test2
具有相同的 inode 編號,但test3
具有不同的編號。現在,如果允許您對目錄執行此操作,則文件系統中不同點的兩個不同目錄可能指向同一事物。事實上,子目錄可以指向它的祖父母,從而創建一個循環。
為什麼這個循環是一個問題?因為當您遍歷時,無法檢測到您正在循環(在遍歷時不跟踪 inode 編號)。想像一下,您正在編寫
du
命令,該命令需要通過子目錄進行遞歸以了解磁碟使用情況。怎麼du
知道它什麼時候遇到循環?du
為了完成這個簡單的任務,它很容易出錯並且必須做很多簿記。符號連結是完全不同的野獸,因為它們是許多文件文件系統 API 傾向於自動遵循的特殊類型的“文件”。請注意,符號連結可以指向不存在的目標,因為它們按名稱指向,而不是直接指向 inode。這個概念對硬連結沒有意義,因為僅僅存在“硬連結”就意味著文件存在。
那麼為什麼可以
du
輕鬆處理符號連結而不是硬連結呢?我們能夠在上面看到硬連結與普通目錄條目沒有區別。然而,符號連結是特殊的、可檢測的和可跳過的!du
注意到符號連結是符號連結,並完全跳過它!% ls -l total 4 drwxr-xr-x 3 danny staff 102 Oct 13 18:14 test1/ lrwxr-xr-x 1 danny staff 5 Oct 13 18:13 test2@ -> test1 % du -ah 242M ./test1/bigfile 242M ./test1 4.0K ./test2 242M .