最近前端包管理器pnpm真的是太火了,大量的文章分析了pnpm的原理。瞭解之後,發現pnpm整個架構都是基於硬連結和軟連結組織的,但我對這兩個概念比較模糊,所以想研究一下。
眾所周知,Unix/Linux系統中一切皆檔案。可見,檔案在Linux系統中非常重要。我們平常比較直觀的對於檔案的感受肯定是檔名和檔案內容。但在Linux的檔案系統中,除了檔名和檔案內容,還有一個很重要的概念,就是inode。
維基百科這樣描述inode:
The inode (index node) is a data structure in a Unix-style file system that describes a file-system object such as a file or a directory. Each inode stores the attributes and disk block locations of the object's data.File-system object attributes may include metadata (times of last change,access, modification), as well as owner and permission data.
A directory is a list of inodes with their assigned names. The list includes an entry for itself, its parent, and each of its children.
意思就是:inode是類Unix檔案系統中用來描述檔案系統物件(比如檔案或資料夾)的一種資料結構。它儲存著檔案的各種屬性(最近一次inode變動的時間、最近一次存取的時間、最近一次修改的時間等元資訊,以及許可權資訊等)。資料夾是一組inode,包括自身的入口、父節點的入口以及所有子節點。
其實,inode包含的內容不止上面這些,具體有:
檔案的位元組數
檔案的User ID
檔案的Group ID
檔案的讀、寫、執行許可權
時間戳:ctime,inode上一次變動的時間;mtime,檔案內容上一次變動的時間;atime,檔案上一次開啟的時間
連結數,即有多少個檔名指向這個inode
檔案資料block的位置
Linux使用的ext2/ext3檔案系統中,不同型別的資料存放在不同的區域。inode組成的inode table存放在一個位置,檔案資料塊則存在另外一個位置。
inode不包含檔名,檔名存放在資料夾資訊的結構體裡。檔名相當於inode的別名,便於我們管理和記憶。Linux系統對檔案的操作都是通過inode做到的,當我們修改檔案時,系統從資料夾的資訊結構體裡找到檔名對應的inode,再通過儲存在inode中的檔案資料block地址找到對應的硬碟位置進行讀寫操作。
一般來說,inode與檔名、檔案資料是一對一的關係,但我們可以通過shell命令讓多個檔名指向同一個inode,這種就是硬連結(hard link)。
使用ln <origin> <destination>命令可以建立硬連結,如
ln test.txt test_hard.txt
對應nodejs的fs.link方法。
建立硬連結前,test.txt可以這樣表示:
建立硬連結後:
可以看到,test_hard.txt的inode跟原始檔test.txt使用的是同一個,只是現在連結數變成2了。
我們可以執行ls -li檢視一下。
第一列是inode number,可以看到都是13029546,所以兩個檔案使用的是同一個inode。第二列是許可權資訊,第四列是擁有者,第六列是檔案內容大小。可以看到,除了檔名不一樣之外,硬連結建立的檔案跟原始檔的所有元資訊完全一樣。第三列表示連結數,可以看到,目前連結數為2。
由於硬連結檔案和原始檔使用同一個inode,並指向同一塊檔案資料,除檔名之外的所有資訊都是一樣的。所以這兩個檔案是等價的,可以說是互為硬連結檔案。修改任意一個檔案,可以看到另外一個檔案的內容也會同步變化。
準確來說叫符號連結(symbolic link),一般又叫軟連結(soft link)。與硬連結共用一個inode不同,軟連結會建立新的inode,並指向原始檔。可以理解軟連結就是windows系統中的桌面快捷方式。
建立軟連結的命令和硬連結很像,多了-s引數:ln -s <origin> <destination>:
ln -s test.txt test_symbolic.txt
對應的nodejs的fs.symlink方法。
建立軟連結之後:
原始檔inode的連結數還是1,建立了新的inode,軟連結指向原始檔。
執行ls -li看一下:
可以看到,軟連結的inode number跟原始檔的不一樣,許可權一列開頭為小寫L,表示軟鏈,連結數為1,大小為8個位元組。沒錯,軟鏈檔案也有大小,不過一般很小,畢竟只是一個快捷方式。
檔案重新命名和檔案移動對於Linux系統來說都是檔案絕對路徑的更改。對硬連結來說,檔案重新命名或檔案移動不會改變連結指向,而對軟連結來說,檔案重新命名或檔案移動則使連結斷開,這時通過軟連結修改檔案內容時會重新建立一個新的inode,跟原檔名和檔案資料塊關聯。
rm命令或者nodejs的unlink其實是將inode的連結數減1。對於前文的硬連結,刪除test_hard.txt使得inode1的連結數變成1,當連結數變成0時,系統就會釋放掉這個inode,之後再建立的新檔案就可以使用該inode的inode number了。這時沒有inode指向檔案資料block,所以檔案找不到了。但實際上檔案資料還存在硬碟中,所以經常能看到網上有一些幫助恢復誤刪的檔案的工具。軟連結inode連結數為1,刪除軟連結則系統釋放該inode。
軟連結可以連結檔案和資料夾,但硬連結只能連結檔案。
軟連結可以跨不同的檔案系統建立,但是硬連結不行,因為硬連結是共用一個inode,而不同的檔案系統有不同的inode table。
檔案備份:為了防止重要的檔案被誤刪,檔案備份是一種好的辦法,但拷貝檔案會帶來磁碟空間的消耗。硬連結能不佔用磁碟空間實現檔案備份。
檔案共用:多人共同維護同一份檔案時,可以通過硬連結的方式,在私人目錄裡建立硬連結,每個人的修改都能同步到原始檔,但又避免某個人誤刪就丟掉了檔案的問題。
檔案分類:不同的檔案資源需要分類,比如某個電影即是的分類是外國、懸疑,那我們可以在外國的資料夾和懸疑的資料夾裡分別建立硬連結,這樣可以避免重複拷貝電影浪費磁碟空間。有人可能說,使用軟連結不也可以嗎?是的,但不太好。因為一旦原始檔移動位置或者重新命名,軟連結就失效了。
快捷方式:對於路徑很深的檔案,查詢起來不太方便。利用軟連結在桌面建立快捷方式,可以迅速開啟並編輯檔案。
靈活切換程式版本:對於機器上同時存在多個版本的程式,可以通過更改軟連結的指向,從而迅速切換程式版本。這裡提到了python版本的切換可以這麼做。
動態庫版本管理:不是很懂,具體可以看這裡。
Linux系統通過inode管理檔案,inode儲存著檔案位元組數、檔案許可權、連結數、資料block位置等資訊。
硬連結與原始檔共用inode,除了檔名不同,其他與原始檔一樣。不能對資料夾建立硬連結,不能對不同的檔案系統的檔案建立硬連結。
軟連結類似於windows的快捷方式,有獨立的inode。可以對資料夾或不同檔案系統的檔案建立軟連結。
硬連結和軟連結修改檔案內容都會同步到原始檔,因為本質上它們都是指向原始檔的資料block。
相關推薦:《Linux視訊教學》
以上就是帶你搞懂linux硬連結和軟連結(圖文詳解)的詳細內容,更多請關注TW511.COM其它相關文章!