總結如下:
硬鏈接:在磁盤上有一份內容一樣的文件產生,但不改變文件的Inode,也就是與原文件共用Inode,
軟鏈接:不在磁盤上有一份內容一樣的文件產生(),但產生新的Inode,
文件復制:產生新的文件內容,并且使用新的Inode.
簡單的說軟鏈接相當于快捷方式。
一張粗糙的簡圖:
文件a <-- b(文件a的軟鏈接) 文件a
| |
| |
inode inode <-- b(文件a的硬鏈接)
| |
硬盤 硬盤
文件a ------------->copy b(復制文件a)
| |
| |
inode inode
| |
硬盤 硬盤
鏈接是一種在共享文件和訪問它的用戶的若干目錄項之間建立聯系的一種方法。Linux中包括兩種鏈接:硬鏈接(Hard Link)和軟鏈接(Soft Link),軟鏈接又稱為符號鏈接(Symbolic link)。
一、硬鏈接
硬鏈接說白了是一個指針,指向文件索引節點,系統并不為它重新分配inode??梢杂?ln命令來建立硬鏈接。語法:
ln [options] existingfile newfile ln[options] existingfile-list directory
|
用法: 第一種:為”existingfile”創建硬鏈接,文件名為”newfile”。第二種:在”directory”目錄中,為 ”existingfile-list”中包含的所有文件創建一個同名的硬鏈接。常用可選[options] –f 無論”newfile”存在與否,都創建鏈接。-n 如果”newfile”已存在,就不創建鏈接。
下面舉一些例子:
$ ls –il 13058 -rwx - - - - - - 1 longcheng longcheng 48 8月 5 16:38 file1 13059 -rwx - - - - - - 1 longcheng longcheng 57 8月 5 16:40 file2 $ ln file2 file2hard $ ls –il 13058 -rwx - - - - - - 1 longcheng longcheng 48 8月 5 16:38 file1 13059 -rwx - - - - - - 2 longcheng longcheng 57 8月 5 16:40 file2 13059 -rwx - - - - - - 2 longcheng longcheng 57 8月 5 16:40 file2hard
|
注意在創建鏈接前,file1 顯示的鏈接數目為1,創建鏈接后(1)file1和file1hard的鏈接數目都變為2;(2) file1和file1hard在inode號是一樣的(3) file1和file1hard顯示的文件大小也是一樣??梢娺M行了ln命令的操作結果:file1和file1hard是同一個文件的兩個名字,它們具有同樣的索引節點號和文件屬性,建立文件file1的硬鏈接,就是為file1的文件索引節點在當前目錄上建立一個新指針。如下圖,你可以刪除其中任何一個,如rm file2 ,每次只會刪除一個指針,
鏈接數同時減一,只有將所有指向文件內容的指針,也即鏈接數減為0時,內核才會把文件內容從磁盤上刪除。當前目錄邏輯結構:(不好意思圖沒有顯示出來)。
還可以在不同目錄,但同一文件系統中建立文件的硬鏈接。設file1、file2在目錄/home/longcheng/dir1中,下面的命令,在/home/longcheng中建立file2的硬鏈接。
ln file2 /home/longcheng/file2hard
|
下面的程序,是將dir1目錄中所有文件,在目錄dir2中建立硬鏈接
$mkdir dir2 $ln /home/longcheng/dir1/* /home/longcheng/dir2
|
如果使用了 ln –f existingfile newfile,如果newfile已經存在,則無論原來newfile是什么文件,只用當前用戶對它有寫權限,newfile就成為exisitngfile的硬鏈接文件。
盡管硬鏈接節省空間,也是Linux系統整合文件系統的傳統方式,但是存在一下不足之處:(1)不可以在不同文件系統的文件間建立鏈接(2)只有超級用戶才可以為目錄創建硬鏈接。雖然很多樹上說root用戶可以創建,但是筆者在學習過程中發現即使是root用戶也不能創建,我的系統是Redhat,內核 2.4、2.6都試過,在其他系統中不知道是不是可以。
二、軟鏈接(符號鏈接)
軟鏈接克服了硬鏈接的不足,沒有任何文件系統的限制,任何用戶可以創建指向目錄的符號鏈接。因而現在更為廣泛使用,它具有更大的靈活性,甚至可以跨越不同機器、不同網絡對文件進行鏈接。
建立軟鏈接,只要在ln后面加上選項 –s,下面舉個例子
$ ls -il 13058 -rwx - - - - - - 1 longcheng longcheng 48 8月 5 16:38 file1 13059 -rwx - - - - - - 2 longcheng longcheng 57 8月 5 16:40 file2 13059 -rwx - - - - - - 2 longcheng longcheng 57 8月 5 16:40 file2hard $ln –s file1 file1soft $ls -il 13058 -rwx - - - - - - 1 longcheng longcheng 48 8月 5 16:38 file1 13059 -rwx - - - - - - 2 longcheng longcheng 57 8月 5 16:40 file2 13059 -rwx - - - - - - 2 longcheng longcheng 57 8月 5 16:40 file2hard 13061 lrwxrwxrwx 1 longcheng longcheng 5 8月 5 16:58 file1soft->file1
|
從上面鏈接后的結果可以看出來軟鏈接與硬鏈接,區別不僅僅是在概念上,在實現上也是不同的。區別:硬鏈接原文件&鏈接文件公用一個inode號,說明他們是同一個文件,而軟鏈接原文件&鏈接文件擁有不同的inode號,表明他們是兩個不同的文件;在文件屬性上軟鏈接明確寫出了是鏈接文件,而硬鏈接沒有寫出來,因為在本質上硬鏈接文件和原文件是完全平等關系;鏈接數目是不一樣的,軟鏈接的鏈接數目不會增加;文件大小是不一樣的,硬鏈接文件顯示的大小是跟原文件是一樣的,這用強調,因為是等同的嘛,而這里軟鏈接顯示的大小與原文件就不同了,file1大小是48B,而file1soft是5B,這里面的5實際上就是“file1”的大小。
總之,建立軟鏈接就是建立了一個新文件。當訪問鏈接文件時,系統就會發現他是個鏈接文件,它讀取鏈接文件找到真正要訪問的文件。
在不同系統之間建立軟鏈接、對目錄建立鏈接,這里就不舉例了,讀者可以自己去嘗試,我也是在不斷實踐中學習的。
當然軟鏈接也有硬鏈接沒有的缺點,因為鏈接文件包含有原文件的路徑信息,所以當原文件從一個目錄下移到其他目錄中,再訪問鏈接文件,系統就找不到了,而硬鏈接就沒有這個缺陷,你想怎么移就怎么移;還有它要系統分配額外的空間用于建立新的索引節點和保存原文件的路徑。補充一下:可以通過symlink來查看鏈接文件,可以用 man symlink來學習。
索引節點、硬連接和連接計數
索引節點inode:
引用:Linux為每個文件分配一個稱為索引節點的號碼inode,可以將inode簡單理解成一個指針,它永遠指向本文件的具體存儲位置。系統是通過索引節點(而不是文件名)來定位每一個文件。
例如:
假設我們在硬盤當前目錄下建立了一個名為mytext文本文件,其內容只有一行:
This is my file.
1、當然這行文字一定是存儲在磁盤數據區某個具體位置里(物理上要通過磁頭號、柱面號和扇區號來描述,在本例中假設分別是1、20、30)。
2、假設其inode是262457,那么系統通過一段標準程序,就能將這個inode轉換成存放此文件的具體物理地址(1磁頭、20柱面、30扇區),最終讀出文件的內容:“This is my file.”
3、所以inode是指向一個文件數據區的指針號碼,一個inode對應著系統中唯一的一片物理數據區,而位于兩個不同物理數據區的文件必定分別對應著兩個不同的inode號碼。
文件拷貝命令與硬鏈接的區別:
# cp /home/zyd/mytext newfile
在當前工作目錄建立了一個新文件newfile,其實際操作主要包括如下三步:
引用:1、在當前目錄中增加一個目錄項,其文件名域填入newfile,并分配了一個新的inode,假設是262456。
2、將原文件(在1磁頭、20柱面、30扇區)的內容復制了一份到新的空閑物理塊(假設是1磁頭、20柱面、31扇區)。
3、填寫一些其他關鍵信息,使系統通過這些信息及inode號碼可以完成物理地址的轉換。
所以文件復制要分配新的inode和新的數據區,雖然兩個文件的內容是一樣的。
硬連接hardlink:
引用:我們實際使用文件時一般是通過文件名來引用的。通過上面的討論,我們知道:
1個inode號碼肯定和一片完全屬于一個文件的數據區一一對應。那么一個文件系統中兩個或更多個不同的文件名能否對應同一個文件呢?答案是肯定的。
我們知道inode號碼是記錄在文件名對應的目錄項中的,我們可以使兩個或多個文件的目錄項具有相同的inode值,實際上就使它們對應著同一個文件。
有幾個目錄項具有相同的inode號,我們就說這個文件有幾個硬連接(hardlink),
對于普通文件,ls -l命令的連接計數count域的數值就是本文件擁有的硬連接數。硬連接可以通過ln命令建立,
例如:
# ln /home/zyd/mytext hardlink_mytext
就建立了一個新的文件hardlink_mytext,這個文件的inode同樣是262457。建立硬連接實際上只是增加了一個目錄項,但并復制文件數據區,原文件的數據區由兩個文件共享。這一方面能夠節約大量磁盤空間,同時可以保證兩個文件能同步更新。
'ls -il'可以顯示文件的inode(在下面最左邊):
262456 -rw-rw-r-- 1 zyd zyd 17 Nov 3 14:52 newfile
262457 -rw-rw-r-- 2 zyd zyd 17 Nov 3 14:50 hardlink_mytext
262457 -rw-rw-r-- 2 zyd zyd 17 Nov 3 14:50 mytext
連接計數count:
前面我們介紹了,文件的連接計數域表明本系統中共有幾個文件目錄項的inode和本文件相同,也就是本文件共有幾個硬連接。如上面的例子中hardlink_mytext和mytext文件的count值都是2。
那么對于目錄,其count域的含義是什么呢?目錄的count同樣表示共有多少個目錄項指向此目錄,不過要詳細說明必須進一步解釋VFS文件系統的結構,為簡單起見,只要這樣理解就行了:(count-2)等于本目錄包含的直接子目錄數(就是只包括兒子,不包括孫子啦!)。
例如:如果一個目錄/abc的count域為5,那么/abc目錄一定包含3個子目錄。
引用:進一步說明:
硬連接文件實際上并不是一種新的文件類型,兩個文件互為對方的硬連接。它們應該都是普通文件(誰能告訴我:其它類型的文件可以硬連接嗎?)。兩個文件除了名稱或/和文件目錄不同外,其它部分完全相同,更改了一個文件,另一個的文件長度、內容、更改時間等都將相應發生變化,更改了一個文件的權限位 mode,另一個也會發生同樣的變化。
引用:注意連接計數字段count,互為硬連接的兩個文件的count值都是2,表明有兩個inode指向同一文件的inode。
當我們刪除其中一個文件時,系統首先將(count-1)->;count,如果結果是零,就將其目錄項和數據區都刪除,否則只將本目錄項刪除,數據區仍然保留,仍然可以通過另外的文件名訪問。根據這個特性,可以通過為重要的文件建立硬連接的方法來防止其被誤刪除。
一個文件系統允許的inode節點數是有限的,如果文件數量太多,即使每個文件都是0字節的空文件,系統最終也會因為節點空間耗盡而不能再創建文件。所以當發現不能建立文件時首先要考慮硬盤數據區是否還有空間(可通過du命令),其次還得檢查節點空間。
引用:互為硬連接的多個文件必須位于同一個文件系統上。根設備及任何一個需要mount才能掛接進來的分區、軟盤、NFS、光驅等都是一個 獨立的文件系統,每個文件系統有一個相應的設備號,不同文件系統中具有相同inode節點的文件間沒有任何聯系。系統則通過設備號和inode號的組合 唯一確定一個文件。
Linux之所以能支持多種文件系統,其實是由于Linux提供了一個虛擬文件系統VFS,VFS作為實際文件系統的上層軟件,掩蓋了實際文件系統底層的具體結構差異,為系統訪問位于不同文件系統的文件提供了一個統一的接 口。
實際上許多文件系統并不具備inode結構,其目錄結構也和以上的討論不同,但通過VFS,系統均為其提供了虛擬一致的inode和目錄項結構。
所以,'ls -il'命令實際顯示的inode應該是VFS inode,也就是說,inode是存在于內存中的數據結構,而不一定是實際的硬盤結構。
但為Linux量身定做的ext2文件系統具備實際的inode和連接型目錄項結構,所以,對于ext2文件系統,可以認為我們上面討論的關于硬連接的概念是完全正確的。