硬鏈接(Hard Link)
1. 釋義
是對(duì)原文件起了一個(gè)別名。
2. 特性
(1)硬鏈接有相同的 inode 及 data block;
(2)只能對(duì)已存在的文件進(jìn)行創(chuàng)建;
(3)不能交叉文件系統(tǒng)進(jìn)行硬鏈接的創(chuàng)建;
(4)不能對(duì)目錄進(jìn)行創(chuàng)建,只可對(duì)文件創(chuàng)建;
(5)刪除一個(gè)硬鏈接文件并不影響其他有相同inode號(hào)的文件。
3.創(chuàng)建硬鏈接
ln file link
軟鏈接(Soft Link)
1. 釋義
又被叫為符號(hào)鏈接(symbolic Link),它包含了到原文件的路徑信息。
2. 特性
(1)軟鏈接有自己的文件屬性及權(quán)限等;
(2)可對(duì)不存在的文件或目錄創(chuàng)建軟鏈接;
(3)軟鏈接可交叉文件系統(tǒng);
(4)軟鏈接可對(duì)文件或目錄創(chuàng)建;
(5)創(chuàng)建軟鏈接時(shí),鏈接計(jì)數(shù) i_nlink 不會(huì)增加;
(6)刪除軟鏈接并不影響被指向的文件,但若被指向的原文件被刪除,則相關(guān)軟連接被稱為死鏈接(即 dangling link,若被指向路徑文件被重新創(chuàng)建,死鏈接可恢復(fù)為正常的軟鏈接)。
3. 創(chuàng)建軟鏈接
ln -s file link
區(qū)別
|
|
硬鏈接 |
軟鏈接 |
|
本質(zhì) |
是同一個(gè)文件 |
不是同一個(gè)文件 |
|
跨設(shè)備 |
不支持 |
支持 |
|
inode |
相同 |
不同 |
|
鏈接數(shù) |
創(chuàng)建新的硬鏈接,鏈接數(shù)會(huì)增加,刪除硬鏈接,鏈接數(shù)減少
|
是不同的文件,無(wú)鏈接數(shù)一說(shuō) |
|
目錄 |
不支持 |
支持 |
|
相對(duì)路徑 |
原始文件相對(duì)路徑是相對(duì)于當(dāng)前工作目錄 |
原始文件的相對(duì)路徑是相對(duì)于鏈接文件的相對(duì)路徑 |
|
刪除源文件 |
只是鏈接數(shù)減一,但鏈接文件的訪問(wèn)不受影響 |
鏈接文件將無(wú)法訪問(wèn) |
|
文件類型 |
和原文件相同 |
和原文件無(wú)關(guān) |
|
文件大小 |
和原文件相同 |
原文件的路徑的長(zhǎng)度 |
為什么不允許創(chuàng)建指向目錄的硬鏈接?
以下內(nèi)容翻譯自:
http://unix.stackexchange.com/questions/22394/why-hard-links-not-allowed-to-directories-in-unix-linux
1. 從inode角度談
允許目錄的硬鏈接可能會(huì)打破文件系統(tǒng)的有向無(wú)環(huán)圖結(jié)構(gòu),可能創(chuàng)建目錄循環(huán),這可能會(huì)導(dǎo)致fsck以及其他一些遍歷文件樹(shù)的軟件出錯(cuò)。
首先,要想理解這點(diǎn)必須先了解inode。文件系統(tǒng)中的數(shù)據(jù)保存在磁盤(pán)上的數(shù)據(jù)塊中,而這些數(shù)據(jù)塊由inode集合在一起??梢哉f(shuō)inode就是文件,但是inode缺少文件名,所以就需要鏈接。一個(gè)鏈接其實(shí)就是一個(gè)指向inode的指針。目錄是一個(gè)保存著這些鏈接的inode,目錄中的每一個(gè)文件名都是一個(gè)指向inode的鏈接。這里提一下,UNIX系統(tǒng)中打開(kāi)一個(gè)文件也會(huì)創(chuàng)建一個(gè)鏈接,但是它是不同類型的鏈接(它不是一個(gè)命名鏈接)。
硬鏈接只是一個(gè)指向inode的額外的目錄項(xiàng),當(dāng)你使用ls -l命令查看文件時(shí),文件權(quán)限后面的數(shù)字就是命名連接數(shù)。絕大多數(shù)文件只有一個(gè)鏈接。創(chuàng)建一個(gè)新的硬鏈接到一個(gè)文件會(huì)將兩個(gè)文件名指向同一個(gè)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
現(xiàn)在你可以清楚的看到,其實(shí)并沒(méi)有什么硬鏈接,一個(gè)硬鏈接和正常的名字是一樣的。在上面的例子中,test 和 test1 哪個(gè)是原始文件,哪個(gè)是硬鏈接?其實(shí)你并不能分辨(忽略時(shí)間戳)因?yàn)樗鼈兌际侵赶蛳嗤瑑?nèi)容相同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 標(biāo)志讓 ls 將文件的 inode 號(hào)顯示在第一列)我們可以看到此時(shí) test 和test1 有著相同的inode號(hào)?,F(xiàn)在,如果你被允許在目錄上使用硬鏈接,文件系統(tǒng)中的不同指針的不同目錄項(xiàng)會(huì)指向相同的東西。實(shí)際上,一個(gè)子目錄可以指向他的父目錄從而創(chuàng)建一個(gè)循環(huán)。
為什么需要考慮這個(gè)循環(huán)?因?yàn)楫?dāng)你遍歷目錄樹(shù)時(shí),你沒(méi)有辦法檢測(cè)到循環(huán)(如果您沒(méi)有跟蹤遍歷的inode號(hào))。比如說(shuō),你現(xiàn)在在使用du命令,du需要遍歷所有的子目錄來(lái)了解磁盤(pán)的使用情況。而du命令如何知道它遇到了個(gè)循環(huán)?這很容易發(fā)生錯(cuò)誤。
軟鏈接,亦稱符號(hào)鏈接,是一個(gè)完全不同的東東,因?yàn)樗鼈兪且环N特殊類型的文件(UNIX文件系統(tǒng)中的文件種類包括:普通文件,目錄文件,塊特殊文件,字符特殊文件,F(xiàn)IFO,套接字以及符號(hào)鏈接。比如通過(guò) “ ln -s a b ” 創(chuàng)建的軟鏈接,創(chuàng)建軟鏈接之后文件 b 和 a 的 inode 號(hào)并不一樣,也就是說(shuō)此時(shí)文件 a 和 b 并不是同一文件。 此時(shí)文件 b 中存的是文件 a 的路徑,當(dāng)讀取 b 時(shí),系統(tǒng)識(shí)別出文件 b 是符號(hào)鏈接會(huì)自動(dòng)導(dǎo)向其對(duì)應(yīng)的文件 a。)。注意,一個(gè)符號(hào)鏈接可以指向一個(gè)不存在的目標(biāo),因?yàn)樗麄冎赶虻闹皇敲侄皇侵苯又赶騣node。這與硬鏈接不一樣,因?yàn)橛叉溄泳捅硎究隙ㄓ形募嬖凇?/p>
那么為什么du可以很輕松的處理符號(hào)鏈接而不能處理硬鏈接?我們前面討論過(guò),如果對(duì)目錄使用硬鏈接和正常的目錄是沒(méi)有區(qū)別的,而軟鏈接是特殊的,可檢測(cè)的且可跳過(guò)的。du注意到一個(gè)目錄是一個(gè)符號(hào)鏈接它會(huì)完全跳過(guò)它。
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. 從掛載點(diǎn)角度談
從掛載點(diǎn)角度來(lái)說(shuō),任何目錄有且只有一個(gè)父目錄".."。
pwd的一個(gè)方法就是檢查設(shè)備:"."和".."的inode,如果它們一樣,說(shuō)明你已處于"/"。否則,查找父目錄名稱并入棧,然后比較"../."和"../..",此后比較"../../.""../../.."...。直到抵達(dá)"/"后,開(kāi)始出棧并打印棧中保存的目錄項(xiàng)名稱,最后得到當(dāng)前目錄的完整目錄名。這個(gè)算法依賴于每個(gè)目錄有且只有一個(gè)父目錄。
如果對(duì)目錄的硬鏈接是允許的,".."該指向多個(gè)父目錄中的哪個(gè)?這是一個(gè)“為什么不允許對(duì)目錄的硬鏈接”比較令人信服的理由。而目錄的軟鏈接不會(huì)引發(fā)這種問(wèn)題,如果一個(gè)程序需要,它可以通過(guò)對(duì)路徑名進(jìn)行 lstat() 來(lái)檢測(cè)是否遇到的是符號(hào)鏈接。pwd算法會(huì)返回目標(biāo)目錄的正確的路徑。
3. 總結(jié)
UNIX 文件系統(tǒng)的歷史上,對(duì)目錄的硬鏈接是可能的。但是這可能會(huì)在文件系統(tǒng)樹(shù)中產(chǎn)生循環(huán),而這會(huì)使得遍歷文件系統(tǒng)變得混亂(在《Unix高級(jí)環(huán)境編程》中提到作者Steven在自己的系統(tǒng)上做過(guò)實(shí)驗(yàn),結(jié)果是:創(chuàng)建目錄硬鏈接后,文件系統(tǒng)變得錯(cuò)誤百出)。一個(gè)目錄甚至可以是自身的父目錄,如下圖顯示,在目錄foo中如果創(chuàng)建一個(gè)testdir 的硬鏈接指向 foo 本身,這樣一個(gè)循環(huán)就出現(xiàn)了。
現(xiàn)代文件系統(tǒng)一般禁止這些混淆狀態(tài),只有根目錄保持了特例:根目錄是自身的父目錄。ls /.. 就是根目錄的內(nèi)容。






