本篇文章給大家帶來了關于linux中硬鏈接和軟鏈接的相關知識,其中還有inode的相關問題,希望對大家有幫助。
前言
最近前端包管理器pnpm真的是太火了,大量的文章分析了pnpm的原理。了解之后,發現pnpm整個架構都是基于硬鏈接和軟鏈接組織的,但我對這兩個概念比較模糊,所以想研究一下。
眾所周知,unix/linux系統中一切皆文件。可見,文件在linux系統中非常重要。我們平常比較直觀的對于文件的感受肯定是文件名和文件內容。但在Linux的文件系統中,除了文件名和文件內容,還有一個很重要的概念,就是inode。
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
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
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》