Filesystems

為什麼在 UNIX/Linux 中不允許硬連結到目錄?

  • July 12, 2019

我在教科書中讀到 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 編號。請注意如何testtest2具有相同的 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    .

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