獲獎+答案公布:Linux符號鏈接和硬鏈接的小測試

假設目錄「~」下面不存在a, b, c這樣的文件,在該目錄下面執行如下命令:

題目步驟

$ echo hello > a

$ ln a b

$ ln -s a c

$ rm a

$ echo world > a

請問接下來執行

「cat b」

輸出什麼?執行

"cat c」

輸出什麼?解釋為什麼!詳細論述其中關於inode等的變化。

雖然很多童鞋的答案都是正確的,但是獲獎名單只能有三人。眾多童鞋的回答參見做題免費送書:關於Linux符號鏈接和硬鏈接的小測試的留言。

我們根據答案回復的先後順序,答案的精細度、準確度和完整度,選取了3個優勝者。獲獎名單與答案如下:

wsl

「cat b」 的輸出是 hello, 「cat c」 是world

首先解釋為什麼」cat b「 輸出是hello, b 文件是a 文件的硬鏈接,而硬鏈接實際

是同一個文件,因為他們的inode number 是相同的。比如筆者的測試環境:

$ ls -i a

473972 a

$ln a b

$ ls -i b

473972 b

既然是同一個文件,a 和b 的文件內容相同,雖然第四步刪除了文件a 但是inode 引用數只是減了1,

並不為0,inode 並沒有刪除。

下面解釋為什麼 「cat c」的輸出

首先創建了一個名為c 的軟連接,c 本質上是一個新文件(inode number不同於a)c 的文件內容是a的路徑

$ ls -i c

480580 c

$cat c

hello

此時cat c,默認讀一個link 文件, 內核FOLLOW_LINK, 也就是會讀c 指向的文件a的內容。

第四步刪除了a, 此時c 文件本身不受影響,c文件內容也不受影響,但是如果此時cat c

則會輸出:

cat: c: No such file or directory

因為FOLLOW link目標文件,目標文件已經不存在了。最後一步重新創建了一個a 文件,

cat c 會輸出新創建文件的內容。本質上c 文件始終沒有發生變化,他的內容是就是a 的path.

紅燒的威化餅

cat b顯示的是hello

cat c顯示的是world

原因

echo hello > a 新建a(設inode number為10),內容為hello

ln a b,創建硬鏈接b,和a共用一個inode,不同的dentry

ln -s a c 創建軟連接c指向a,不與a共用inode

rm a 刪除a文件,由於inode10有兩個reference,只把它的reference減1,不刪除數據,但是由於a沒了,

所以c這個軟連接失效。

echo world > a 新建一個新文件,假設inode number為20,內容為world,此時a和b是兩個不同的文件,c是軟鏈接指向a

桂雄~

$ echo hello > a

這裡會創建a文件,此時a文件內容是hello

$ ln a b

這裡創建了一個硬鏈接b,b與a指向同一個inode

$ ln -s a c

這裡創建了一個軟鏈接c,c的文件的實際內容就是a文件的路徑

$ rm a

刪除a文件對b沒有影響,不過這個inode的引i_nlink就會減一,但是c文件的由於保存的是a文件路徑名指向,因此a文件被刪了後,c文件的指向就不存在了,此時cat c會報文件不存在的錯誤。

$ echo world > a

此時echo world又創建一個文件,文件名是a,但是此時的inode已經是重新申請到的,a與b已經不是硬鏈接關係了,但是c文件的軟鏈接文件a又存在了,因此此時c文件cat的話就不會報錯了

cat b的話會輸出hello

因為這是在最初a創建的時候寫進去的,然後b跟他共享了inode,因此文件內容還是hello

cat c的話輸出world

這裡c是新建的a的軟鏈接,這個a文件已經不是原來的a文件,c文件軟鏈接的也不是原來的a文件,而是最後輸入world的時候創建的新的a文件。而c文件軟鏈接到了a文件,因此cat到的就是新的a文件內容。

恭喜這三位童鞋!!祝大家中秋快樂。


查看"Linux閱碼場"精華技術文章請移步:

Linux閱碼場原創精華文章匯總

掃描二維碼關注

"Linux閱碼場"

 

推薦閱讀:

北京外國語大學的入學測試收穫規則
情感測試:4雙板鞋,哪雙最好看?測你今後要走什麼樣的路

TAG:Linux | 測試 | 符號 | 鏈接 | 答案 |