硬鏈接(Hard Link)
1. 釋義
是對原文件起了一個別名。
2. 特性
(1)硬鏈接有相同的 inode 及 data block;
(2)只能對已存在的文件進行創建;
(3)不能交叉文件系統進行硬鏈接的創建;
(4)不能對目錄進行創建,只可對文件創建;
(5)刪除一個硬鏈接文件并不影響其他有相同inode號的文件。
3.創建硬鏈接
ln file link
軟鏈接(Soft Link)
1. 釋義
又被叫為符號鏈接(symbolic Link),它包含了到原文件的路徑信息。
2. 特性
(1)軟鏈接有自己的文件屬性及權限等;
(2)可對不存在的文件或目錄創建軟鏈接;
(3)軟鏈接可交叉文件系統;
(4)軟鏈接可對文件或目錄創建;
(5)創建軟鏈接時,鏈接計數 i_nlink 不會增加;
(6)刪除軟鏈接并不影響被指向的文件,但若被指向的原文件被刪除,則相關軟連接被稱為死鏈接(即 dangling link,若被指向路徑文件被重新創建,死鏈接可恢復為正常的軟鏈接)。
3. 創建軟鏈接
ln -s file link
區別
|
硬鏈接 |
軟鏈接 |
本質 |
是同一個文件 |
不是同一個文件 |
跨設備 |
不支持 |
支持 |
inode |
相同 |
不同 |
鏈接數 |
創建新的硬鏈接,鏈接數會增加,刪除硬鏈接,鏈接數減少
|
是不同的文件,無鏈接數一說 |
目錄 |
不支持 |
支持 |
相對路徑 |
原始文件相對路徑是相對于當前工作目錄 |
原始文件的相對路徑是相對于鏈接文件的相對路徑 |
刪除源文件 |
只是鏈接數減一,但鏈接文件的訪問不受影響 |
鏈接文件將無法訪問 |
文件類型 |
和原文件相同 |
和原文件無關 |
文件大小 |
和原文件相同 |
原文件的路徑的長度 |
為什么不允許創建指向目錄的硬鏈接?
以下內容翻譯自:
http://unix.stackexchange.com/questions/22394/why-hard-links-not-allowed-to-directories-in-unix-linux
1. 從inode角度談
允許目錄的硬鏈接可能會打破文件系統的有向無環圖結構,可能創建目錄循環,這可能會導致fsck以及其他一些遍歷文件樹的軟件出錯。
首先,要想理解這點必須先了解inode。文件系統中的數據保存在磁盤上的數據塊中,而這些數據塊由inode集合在一起。可以說inode就是文件,但是inode缺少文件名,所以就需要鏈接。一個鏈接其實就是一個指向inode的指針。目錄是一個保存著這些鏈接的inode,目錄中的每一個文件名都是一個指向inode的鏈接。這里提一下,UNIX系統中打開一個文件也會創建一個鏈接,但是它是不同類型的鏈接(它不是一個命名鏈接)。
硬鏈接只是一個指向inode的額外的目錄項,當你使用ls -l命令查看文件時,文件權限后面的數字就是命名連接數。絕大多數文件只有一個鏈接。創建一個新的硬鏈接到一個文件會將兩個文件名指向同一個inode。
xx@xx:~/test$ touch test
xx@xx:~/test$ ls -l
total 0
-rw-r--r-- 1 long long 0 Apr 16 16:56 test
xx@xx:~/test$ ln test test1
xx@xx:~/test$ ls -l
total 0
-rw-r--r-- 2 xx xx 0 Apr 16 16:56 test
-rw-r--r-- 2 xx xx 0 Apr 16 16:56 test1
現在你可以清楚的看到,其實并沒有什么硬鏈接,一個硬鏈接和正常的名字是一樣的。在上面的例子中,test 和 test1 哪個是原始文件,哪個是硬鏈接?其實你并不能分辨(忽略時間戳)因為它們都是指向相同內容相同inode的鏈接。
xx@xx:~/test$ ls -li
total 0
2114356 -rw-r--r-- 2 xx xx 0 Apr 16 16:56 test
2114356 -rw-r--r-- 2 xx xx 0 Apr 16 16:56 test1
使用ls -li (-i 標志讓 ls 將文件的 inode 號顯示在第一列)我們可以看到此時 test 和test1 有著相同的inode號。現在,如果你被允許在目錄上使用硬鏈接,文件系統中的不同指針的不同目錄項會指向相同的東西。實際上,一個子目錄可以指向他的父目錄從而創建一個循環。
為什么需要考慮這個循環?因為當你遍歷目錄樹時,你沒有辦法檢測到循環(如果您沒有跟蹤遍歷的inode號)。比如說,你現在在使用du命令,du需要遍歷所有的子目錄來了解磁盤的使用情況。而du命令如何知道它遇到了個循環?這很容易發生錯誤。
軟鏈接,亦稱符號鏈接,是一個完全不同的東東,因為它們是一種特殊類型的文件(UNIX文件系統中的文件種類包括:普通文件,目錄文件,塊特殊文件,字符特殊文件,FIFO,套接字以及符號鏈接。比如通過 “ ln -s a b ” 創建的軟鏈接,創建軟鏈接之后文件 b 和 a 的 inode 號并不一樣,也就是說此時文件 a 和 b 并不是同一文件。 此時文件 b 中存的是文件 a 的路徑,當讀取 b 時,系統識別出文件 b 是符號鏈接會自動導向其對應的文件 a。)。注意,一個符號鏈接可以指向一個不存在的目標,因為他們指向的只是名字而不是直接指向inode。這與硬鏈接不一樣,因為硬鏈接就表示肯定有文件存在。
那么為什么du可以很輕松的處理符號鏈接而不能處理硬鏈接?我們前面討論過,如果對目錄使用硬鏈接和正常的目錄是沒有區別的,而軟鏈接是特殊的,可檢測的且可跳過的。du注意到一個目錄是一個符號鏈接它會完全跳過它。
xx@xx:~/test$ ln -s /home/xx/Videos test2
xx@xx:~/test$ ls -l
total 0
-rw-r--r-- 2 xx xx 0 Apr 16 16:56 test
-rw-r--r-- 2 xx xx 0 Apr 16 16:56 test1
lrwxrwxrwx 1 xx xx 17 Apr 16 17:31 test2 -> /home/xx/Videos
xx@xx:~/test$ du -ah
0 ./test
0 ./test2
4.0K .
2. 從掛載點角度談
從掛載點角度來說,任何目錄有且只有一個父目錄".."。
pwd的一個方法就是檢查設備:"."和".."的inode,如果它們一樣,說明你已處于"/"。否則,查找父目錄名稱并入棧,然后比較"../."和"../..",此后比較"../../.""../../.."...。直到抵達"/"后,開始出棧并打印棧中保存的目錄項名稱,最后得到當前目錄的完整目錄名。這個算法依賴于每個目錄有且只有一個父目錄。
如果對目錄的硬鏈接是允許的,".."該指向多個父目錄中的哪個?這是一個“為什么不允許對目錄的硬鏈接”比較令人信服的理由。而目錄的軟鏈接不會引發這種問題,如果一個程序需要,它可以通過對路徑名進行 lstat() 來檢測是否遇到的是符號鏈接。pwd算法會返回目標目錄的正確的路徑。
3. 總結
UNIX 文件系統的歷史上,對目錄的硬鏈接是可能的。但是這可能會在文件系統樹中產生循環,而這會使得遍歷文件系統變得混亂(在《Unix高級環境編程》中提到作者Steven在自己的系統上做過實驗,結果是:創建目錄硬鏈接后,文件系統變得錯誤百出)。一個目錄甚至可以是自身的父目錄,如下圖顯示,在目錄foo中如果創建一個testdir 的硬鏈接指向 foo 本身,這樣一個循環就出現了。

現代文件系統一般禁止這些混淆狀態,只有根目錄保持了特例:根目錄是自身的父目錄。ls /.. 就是根目錄的內容。