Linux中的硬鏈接和軟鏈接
節選自南大蔣炎巖老師操作系統網絡課程筆記:(2021) 24 [持久化] 文件系統API
硬(hard)鏈接
UNIX文件指針
在UNIX中,文件和目錄完全不是同一個概念,雖然我們平時看著它們仿佛并列地躺在某個文件夾下。但實際上,目錄是樹狀結構組織的,而文件,卻是每個目錄指向某個文件的指針。并且,每個文件都有一個編號,可能會有多個目錄下的多個指針都指向同一個編號的文件。它們雖然存在于不同的目錄下,甚至名稱也不同,但是同一個編號的文件是完全相同的,修改也是同步的。如下圖所示:
我們可以做這樣的測試:
創建測試目錄并在其中的a.txt
寫入Hello World!
mkdir test && cd test && touch a.txt
vim a.txt # 寫入 Hello World!
創建a.txt
的硬鏈接b.txt
:
ln a.txt b.txt
我們查看兩個文件的內容,輸出顯示都是同樣的Hello World:
cat *.txt
# 輸出:
# Hello World!
# Hello World!
這時,我們修改b.txt
的內容為Hello World! Changed~
,再查看兩個文件的內容:
vim b.txt # 更改為 Hello World! Changed~
cat *.txt
# 輸出:
# Hello World! Changed~
# Hello World! Changed~
結果兩個文件都被修改了,這就是硬鏈接,我們可以通過-i
參數查看文件的編號:
ls -i
# 輸出:
# 8593746 a.txt 8593746 b.txt
可以看到,兩個文件其實是同一個編號的文件的不同鏈接。即硬鏈接的圖示如下:
硬鏈接
注意:
- 目錄中僅存儲指向文件數據的指針
- 允許一個文件被多個目錄引用
- 不能鏈接目錄 ?
- 不能跨文件系統 ?
小知識:其實所有的文件都是硬連接 (ls -i
查看)
- 刪除的系統調用稱為 “unlink” (引用計數)
應用場景
可以給文件起別名,同步,省空間。
需求:系統中可能有同一個運行庫的多個版本
libc-2.27.so
,libc-2.26.so
, …- 還需要一個 “當前版本的 libc”
- 程序需要鏈接 “
libc.so.6
” - 能否避免文件的一份拷貝?
- 程序需要鏈接 “
軟(symbolic)鏈接
軟鏈接:在文件里存儲一個 “跳轉提示”,相當于”快捷方式“。
- 軟鏈接也是一個文件
- 當引用這個文件時,去找另一個文件
- 另一個文件的絕對/相對路徑以文本形式存儲在文件里
- 可以跨文件系統、可以鏈接目錄、……好處多多
- 甚至,符號鏈接可以指向一個暫時不存在的文件或目錄,只要這個不存在文件或目錄將來某天存在了,這個符號鏈接就會生效
ln -s
創建軟鏈接,用的是symlink
系統調用。現在系統中/lib
下的共享庫,通常都是軟鏈接。
我們接著上面硬鏈接的例子來看一下二者的區別:
再在測試目錄下創建a.txt
的軟鏈接c.txt
:
ln -s a.txt c.txt
我們用-li參數查看測試目錄中的三個文件:
ls -li
# 輸出
# 8593746 -rw-rw-r-- 2 ps ps 22 10月 1 22:14 a.txt
# 8593746 -rw-rw-r-- 2 ps ps 22 10月 1 22:14 b.txt
# 8593742 lrwxrwxrwx 1 ps ps 5 10月 1 22:35 c.txt -> a.txt
在這里,b,c分別是a的硬、軟鏈接。可以看到,a和c的文件編號是不一樣的,因為它們是軟鏈接,并且可以看到,c作為a的軟鏈接,會有一個箭頭指向a。但是,它們的修改仍然是同步的,因為我們在試圖修改c的時候,系統會順著上面輸出的軟鏈接箭頭去尋找,直到找到一個真實的文件或者目錄。我們還是來試一下:
vim c.txt # 修改為Hello World! Changed~ Soft~
cat *.txt
# 輸出:
# Hello World! Changed~ Soft~
# Hello World! Changed~ Soft~
# Hello World! Changed~ Soft~
與預期一致。此時測試目錄下的鏈接關系應該如下圖所示:
軟鏈接可能帶來的麻煩
軟鏈接可以隨意創建 (當前可能不合法;但未來可能合法),操作系統在處理軟鏈接時會執行路徑解析,,允許多次間接鏈接,會有意想不到的復雜性 ,a → b → c (遞歸解析)。可以創建軟連接的硬鏈接 (因為軟鏈接也是文件),通過ls -i
可以看到。
符號鏈接成環?ln -s . a
。所有處理符號鏈接的程序 (tree, find, …) 都要考慮遞歸的情況。它們默認遇到軟鏈接就跳過,如果加上-L參數強制使它們考慮軟鏈接的話,它們也會很小心的檢測成環和遞歸的情況并適時退出。