認識Linux系統中的inode,硬鏈接和軟鏈接


在學習和創建軟鏈接遇到了一點問題,總結一下:

在當前文件夾下面建立了兩個臨時文件夾tempdir1和tempdir2,然后在tempdir2里面創建了一個hello文件,然后用指令ln -s tempdir2/hello tempdir1/soft-hello-link在tempdir1目錄下創建一個軟鏈接,用tree指令來查看一下當前目錄樹結構:

用ls -l命令來查看一下soft-hello-link文件,可以發現文件權限的第一個是l,表示這是一個鏈接文件。

查看里面的內容,這時候發現tempdir2里面的hello可以查看,但是tempdir1里面的soft-hello-link顯示沒有那個文件或目錄,我進入tempdir1查看了一下soft-hello-link,意識到這可能是絕對地址的問題,也就是說進行軟鏈接的時候要把絕對地址用上,而現在tempdir1里面的soft-hello-link->tempdir2/hello,根據軟鏈接的特性,應該是在目錄樹中找tempdir2/hello,而實際上的絕對地址應該是/home/carl/OSExam/E4/tempdir2/hello,自然是查找不到的,為了驗證我的想法,我重新在tempdir1中鏈接了一個不存在的文件,果然,也會鏈接成功也會顯示這個文件是個鏈接:

當我在tempdir1和tempdir2的父目錄中嘗試指令ln -s ./tempdir2/hello tempdir1/soft-hello-link的時候,我以為在shell里面,會把./tempdir2/soft-hello-link解釋成絕對路徑的時候,發現ln命令只是單純地把第二個參數的文本復制過去,既不會檢查這個文件是否真實存在,也不會對文件的路徑進行解析。

最后,我利用絕對路徑,終於是正常的了,而且這時候這個鏈接文件顯示顏色是藍色,證明正常情況下軟鏈接的文件應該是藍色,而存在錯誤(鏈接指向的文件不存在)則是顯示紅色,背景也會加深(看來圖形界面的256色還是要比字符模式的16色要方便一點點呀)。此時訪問也可以正常顯示內容了。

 

軟鏈接之所以會出現上面的情況,是因為軟鏈接是重新創建了一個文件(inode號都不一樣),而這個文件里面存了相應文件的路徑,所以他是通過文件的訪問名稱來原來的文件的。由於是新創建的文件,所以並不會檢查文件是否存在,也就不會把文件的路徑轉化為絕對路徑了。而硬鏈接,實際上給指向文件是在目錄樹中不同位置的添加了一個新的名稱標識,它與原來目錄的地位是相同的,我們用ls -i來查看兩個目錄項所對應的索引節點號是相同的:

因此,由於是指向目錄樹中的某個存在的文件,硬鏈接實際上是會進行文件檢查的,比如我對tempdir1和tempdir2的父目錄中不存在的文件s進行一個硬鏈接:ln s tempdir1/hard-link ,這條指令是不會像軟鏈接一樣執行成功的,實惠報錯的:

用tree指令來觀察一下建立硬鏈接后目錄數的層次結構:

由於硬鏈接是對某個文件在目錄樹中不同位置增加一個新的名稱標識而已,所以inode號是一樣的,文件的訪問權限也是一樣的,就是同一個文件,可以通過ls指令來觀察硬鏈接和原文件的相關信息,stat命令用於輸出文件的inode儲存的文件元信息(metadata),可以看到這包括文件的字節數、文件的用戶ID、文件的組ID、文件的權限、文件的時間戳(包括最近訪問時間(指讀取文件內容)、最近更改時間(指更改文件內容)、最近改動時間(指更改文件狀態,比如權限等),但是不同於windows,linux沒有記錄創建時間)、硬鏈接的數目、文件類型、設備號、inode所使用的block數、文件數舉block的位置等等,這里的硬鏈接數目是2:

而我們再查看剛剛軟鏈接的信息,會發現是另外一個新文件的信息,inode都不一樣,文件的權限也不一樣:

從上面的圖我們可以看到軟鏈接的文件大小為36,為什么是36呢?原因就是軟鏈接其實存放這的是內容是指向文件的路徑,這里是“/home/carl/OSExams/E4/tempdir2/hello”,不多不少,剛好36。而原文件hello和硬鏈接的大小為11,那是因為里面存放了“hello dir2”,我一看,這明明只有10個字符啊,也沒有換行(我使用echo hello dir2 > hello進行創建的),這也不是c語言應該不是字符結束符'\0',那肯定是有什么特殊符號我看不到的。然后打開vim,輸入:set list查看hello的特殊字符($表示換行符,^I表示tab制表符),發現末尾竟然有一個換行符$:

上網百度了一下,發現在創建一個文件的時候(ps:這里我只實驗通過vim、gedit方式創建),linux系統會確保最后一個字符是換行符!而通過echo來創建文件的話,也會在末尾自動添加一個換行符,原因是echo默認輸出完就換行的,可以通過echo來驗證,通過命令行提示符我們可以看出echo輸出確實會換行:

而如果echo指令帶上參數-n,則就不會換行:

因此,如果想要創建一個末尾沒有換行符的文件的時候,比如“hello dir2”我就是想要純粹的“hello dir2”我並不想系統末尾幫我保存一個換行符,我可以通過這種方式進行創建:

可是奇怪的是,我用vim打開hello-file的時候,輸入:set list還是能發現最后有個換行符$(查了一下好象是因為vi會確保文件的最后一個符號一定是換行符,所以會顯示出來):

我以為只要用vim打開以后再保存就會顯示換行符了,可是並沒有,大小依然是10,cat查看也不會輸出換行,這大概是系統檢測到我沒有進行任何操作,所以保存了也不會對硬盤中的文件進行任何修改:

但是,我一旦用gedit打開,打開以后馬上按保存,系統就已經在末尾自動添加一個換行符了,和vim不同:

好了,這不是關鍵,只是好奇亂看了一下啊而已,回到原來的硬鏈接和軟鏈接。對於硬鏈接,如果刪除了原文件,只會在inode記錄的元信息中的硬鏈接數-1,直到所有硬鏈接都刪除了(硬鏈接數為0)對應的磁盤上的文件才會被刪除;而對於軟鏈接,如果把原文件刪除了,則無法進行訪問了,而且會顯示鏈接文件是錯誤的(紅色字體,背景加深):

這時候,只要在tempdir2中對tempdir1的硬鏈接文件再進行一個硬鏈接,tempdir1中的軟鏈接也會恢復正常:

 

過程查了一下相關知識,把看到的覺得不錯的文章記錄下來。

1. Inode
在Linux系統中,每個文件都有一個inode(索引節點),inode存儲了文件的元信息,主要有:
*文件的字節數
*文件的用戶ID
*文件的組ID
*文件的read,write,execute權限
*文件的時間戳:最近的產生時間,最近一次存取時間,最近一次修改時間
*鏈接數
*inode所使用的block數
*文件數據block的位置
等等

這里補充一點,文件是存儲在硬盤上的。硬盤的最小存儲單位是扇區(Sector),每 個扇區存儲512字節。出於效率的考慮,操作系統不是按一個扇區一個扇區的讀取文件,而是一次連續讀取多個扇區,通常被稱作塊(block)。塊是文件存 取的最小單位,一般為4K,即連續的8個扇區組成一個塊。因為inode要存儲文件的元信息,它也會消耗硬盤空間,一般是128或256字節。inode 節點的總數,在硬盤格式化的時候就給定了,一般是每1KB或2KB設置一個inode。有時候會遇到剩余硬盤空間足夠,但系統仍然提示空間不足的情況,其 原因就是inode用完了。

Linux系統中每個文件都有文件名,但是操作系統並不是按文件名來識別文件,而是按 inode號來識別不同的文件。當用戶打開一個文件時,主要有3步:1. 系統找到文件名對應的inode號;2. 通過inode號獲取inode信息;3. 根據inode信息找到文件所在的block並讀取數據。另外,因為系統是按inode來識別文件,所以直接刪除inode就能到達刪除文件的作用。

在Linux中有“一切皆文件”的說法,目錄也被看作一種文件。當創建目錄時,一般會生成兩個目錄項:“.”和“..”。可以看成是兩個硬鏈接,前者的inode號就是當前目錄的inode 號;后者的inode號就是當前目錄的父目錄的inode號。

<附>
查看inode信息的方法:
---
stat 文件名
---
查看inode號的方法:
---
ls -i 文件名
---
查看硬盤分區的inode總數和已使用inode的數量:
---
df -i
---

2. 硬鏈接和軟鏈接
1)硬鏈接(hard link)
硬鏈接打破了文件名和inode號“一一對應”的關系,實現讓多個文件名指向同一個inode號。刪除其中一個文件名,不影響另一個文件名的訪問。硬鏈接生成的文件大小與原文件一樣大。創建硬鏈接的方法如下:
---
ln 源文件 目標文件
---
每當創建一個硬鏈接,inode信息里記錄的鏈接數就會加1;反之,刪除一個文件名,鏈接數就會減1。當鏈接數為0時,說明沒有文件指向該inode,系統將回收該inode號,以及所對應的block區域。

2)軟鏈接(soft link)
軟鏈接又叫符號鏈接(symbolic link)。軟鏈接生成的文件是對源文件的引用,但是與原文件的inode號不同。訪問軟鏈接生成的文件時,其實是讀取的源文件。當源文件被刪除時,系統會提示找不到文件的錯誤信息。可以用如下方法創建軟鏈接:
---
ln -s 源文件 目標文件
---

3)比較
*硬鏈接指向源文件索引節點,不重新分配inode;軟鏈接生成時分配新的inode
*硬鏈接文件大小與源文件大小相同;軟鏈接文件大小與源文件不同,一般較小
*硬鏈接不能跨越文件系統;軟鏈接可以
*一般情況下,不能為目錄創建硬鏈接;但可以為目錄創建軟鏈接

轉自:

http://blog.csdn.net/felix_yujing/article/details/38024987


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com