Linux系統硬鏈接和軟鏈接說明 - 運維筆記


 

在linux系統中有種文件是鏈接文件,可以用來解決文件的共享使用。鏈接的方式可以分為兩種,一種是硬鏈接(Hard Link),另一種是軟鏈接或者也稱為符號鏈接(Symbolic Link)。先來查看下Linux系統中哪些是鏈接文件:

[root@ss-server lib64]# ls -l
drwxr-xr-x.  4 root root     4096 Nov 29  2018 nss
drwxr-xr-x.  3 root root     4096 Oct 31  2018 openssl
lrwxrwxrwx.  1 root root       19 Nov 29  2018 p11-kit-proxy.so -> libp11-kit.so.0.3.0
lrwxrwxrwx.  1 root root       13 Nov 29  2018 p11-kit-trust.so -> libnssckbi.so
drwxr-xr-x  29 root root     4096 Jan  2  2019 perl5
drwxr-xr-x.  2 root root     4096 Nov 29  2018 pkcs11

第一列權限位標識第一個字符顯示的是文件類型,-為一般文件,d為目錄,而l顯示的就是鏈接文件,並且是軟鏈接文件(符號鏈接文件)!

一、硬鏈接說明
硬鏈接是指通過索引節點來進行鏈接。在Linux文件系統中,保存在磁盤分區中的文件不管是什么類型都會給它分配一個編號,這個編號被稱為索引節點編號(Inode Index)或者Inode,它是文件或目錄在一個文件系統中的唯一標識,文件的實際數據放置在數據區域(data block),它存儲着文件重要參數信息,即元數據 (metadata),比如創建時間、修改時間、文件大小、屬主、歸屬的用戶組、讀寫權限、數據所在block號等,如下圖所示:

在Linux系統中,多個文件名指向同一索引節點(Inode)是正常且允許的,一般這種鏈接就成為硬鏈接。硬鏈接的作用之一是允許一個文件擁有多個有效路徑名,這樣用戶就可以建立硬鏈接到重要的文件,以防止"誤刪"源數據不過硬鏈接只能在同一文件系統中的文件之間進行鏈接,不能對目錄進行創建。之所以文件建立了硬鏈接就會防止數據誤刪,是因為文件系統的原理是,只要文件的索引節點還有一個以上的鏈接(僅刪除了該文件的指向),只刪除其中一個鏈接並不影響索引節點本身和其他的鏈接(數據的實體並未刪除),只有當最后一個鏈接被刪除后,此時如果有新數據要存儲到磁盤上,被刪除的文件的數據塊及目錄的鏈接才會被釋放,空間被新數據暫用覆蓋。

二、軟鏈接說明
軟鏈接也叫符號鏈接,類似於windows系統中的快捷方式,與硬鏈接不同,軟鏈接就是一個普通文件,只是數據塊內容有點特殊,文件用戶數據塊中存放的內容是另一文件的路徑名的指向,通過這個方式可以快速定位到軟連接所指向的源文件實體。軟鏈接可對文件或目錄創建。

軟鏈接作用
1.  便於文件的管理,比如把一個復雜路徑下的文件鏈接到一個簡單路徑下,方便用戶訪問。
2.  節省空間解決空間不足問題,某個文件系統空間已經用完了,但是現在必須在該文件系統下創建一個新的目錄並存儲大量的文件,那么可以把另一個剩余空間較多的文件系統中的目錄鏈接到該文件系統中。

需要注意:刪除軟鏈接並不影響被指向的文件,但若被指向的原文件被刪除,則相關軟連接就變成了死鏈接。

三、軟連接和硬鏈接的特點

軟鏈接
1. 軟鏈接是存放另一個文件的路徑的形式存在。
2. 軟鏈接可以跨文件系統 ,硬鏈接不可以。
3. 軟鏈接可以對一個不存在的文件名進行鏈接,硬鏈接必須要有源文件。
4. 軟鏈接可以對目錄進行鏈接。

硬鏈接
1.  硬鏈接,以文件副本的形式存在。但不占用實際空間。
2.  不允許給目錄創建硬鏈接。
3.  硬鏈接只有在同一個文件系統中才能創建。
4.  刪除其中一個硬鏈接文件並不影響其他有相同 inode 號的文件。

需要明白:不論是硬鏈接或軟鏈接都不會將原本的檔案復制一份,只會占用非常少量的磁碟空間。

四、鏈接文件創建命令 "ln"

ln命令格式
ln [參數] [源文件或目錄] [目標文件或目錄]

主要參數
-i     交互模式,文件存在則提示用戶是否覆蓋。
-s    軟鏈接(符號鏈接)。
-d    允許超級用戶制作目錄的硬鏈接。
-b    刪除,覆蓋以前建立的鏈接

軟鏈接,即符號鏈接創建方法
# ln -s source target

硬鏈接,即實體鏈接創建方法
# ln source target

鏈接操作示例

給文件創建硬鏈接
[root@ss-server ~]# mkdir /opt/test             #創建測試目錄
[root@ss-server ~]# cd /opt/test
[root@ss-server test]# touch file1
[root@ss-server test]# ll
total 0
-rw-r--r-- 1 root root 0 Dec  9 16:38 file1
[root@ss-server test]# ln file1 file_hard       #在默認不帶參數情況下,ln命令創建的是硬鏈接。
[root@ss-server test]# ll
total 0
-rw-r--r-- 2 root root 0 Dec  9 16:38 file1
-rw-r--r-- 2 root root 0 Dec  9 16:38 file_hard
 
給文件創建軟鏈接
[root@ss-server test]# ln -s file1 file_soft    #創建軟鏈接用"-s"參數
[root@ss-server test]# ll
total 0
-rw-r--r-- 2 root root 0 Dec  9 16:38 file1
-rw-r--r-- 2 root root 0 Dec  9 16:38 file_hard
lrwxrwxrwx 1 root root 5 Dec  9 16:39 file_soft -> file1   #軟鏈接文件
 
硬鏈接是有着相同 inode 號僅文件名不同的文件,用ls命令查看。
[root@ss-server test]# ls -li
total 0
917510 -rw-r--r-- 2 root root 0 Dec  9 16:38 file1
917510 -rw-r--r-- 2 root root 0 Dec  9 16:38 file_hard
917511 lrwxrwxrwx 1 root root 5 Dec  9 16:39 file_soft -> file1
 
如上:
源文件和硬鏈接文件inode號相同 (第一列就是inode號),指向同一個索引節點。
軟鏈接是一個鏈接文件,文件模式那塊前面有個l字母,表示是個鏈接文件。
 
硬鏈接不能指向目錄
[root@ss-server test]# mkdir litest
[root@ss-server test]# ln litest li_hard
ln: ‘litest’: hard link not allowed for directory
 
軟鏈接可以執行目錄
[root@ss-server test]# ln -s litest li_soft
[root@ss-server test]# ll
total 4
-rw-r--r-- 2 root root    0 Dec  9 16:38 file1
-rw-r--r-- 2 root root    0 Dec  9 16:38 file_hard
lrwxrwxrwx 1 root root    5 Dec  9 16:39 file_soft -> file1
lrwxrwxrwx 1 root root    6 Dec  9 16:48 li_soft -> litest
drwxr-xr-x 2 root root 4096 Dec  9 16:47 litest

覆蓋以前建立的鏈接,使用-b參數,相當於變相刪除鏈接文件
[root@ss-server test]# ln test1 test_hard
ln: failed to create hard link ‘test_hard’: File exists
[root@ss-server test]# 
[root@ss-server test]# ln -b test1 test_hard
[root@ss-server test]# ln -s -b litest li_soft
[root@ss-server test]# ln -s -b test1 test_soft 
 
刪除文件測試
[root@ss-server test]# echo "this is test" > file1    #向文件中添加數據
[root@ss-server test]# cat file1                      #查看文件內容
this is test
[root@ss-server test]# cat file_hard file_soft        #查看硬鏈接和軟鏈接文件內容是否一致
this is test
this is test
 
[root@ss-server test]# rm -f file1  #刪除源文件
[root@ss-server test]# ls -li
total 8
917510 -rw-r--r-- 1 root root   13 Dec  9 16:49 file_hard
917511 lrwxrwxrwx 1 root root    5 Dec  9 16:39 file_soft -> file1
917513 lrwxrwxrwx 1 root root    6 Dec  9 16:48 li_soft -> litest
917512 drwxr-xr-x 2 root root 4096 Dec  9 16:47 litest
 
發現硬鏈接文件存在 內容和源文件內容一樣!
原因:雖然刪除源文件,但是仍然有硬鏈接指向源文件inode節點,所以不會被釋放刪除,這里只是刪除file1源文件到inode節點的鏈接。
[root@ss-server test]# cat file_hard
this is test
 
發現軟鏈接文件已經不存在了,目錄還會顯示這個文件,就是軟鏈接文件已經失效。
[root@ss-server test]# cat file_soft
cat: file_soft: No such file or directory
 
刪除軟鏈接(直接rm刪除即可)
[root@ss-server test]# rm -f file_soft   #直接刪除這個軟鏈接文件就行
[root@ss-server test]# ll -li
total 8
917510 -rw-r--r-- 1 root root   13 Dec  9 16:49 file_hard
917513 lrwxrwxrwx 1 root root    6 Dec  9 16:48 li_soft -> litest
917512 drwxr-xr-x 2 root root 4096 Dec  9 16:47 litest
 
可以使用unlink命令取消鏈接關系(硬鏈接和軟鏈接都可以)
[root@ss-server test]# unlink file_hard
[root@ss-server test]# unlink li_soft
[root@ss-server test]# ll -li
total 4
917512 drwxr-xr-x 2 root root 4096 Dec  9 16:47 litest

五、cp和mv場景下的鏈接情況

1)如果對一個軟鏈接文件再次進行硬連接,則硬連接之后的那個文件還是軟鏈接文件!
[root@ss-server test]# touch test1
[root@ss-server test]# ln -s test1 test_soft
[root@ss-server test]# ls -l
total 4
drwxr-xr-x 2 root root 4096 Dec  9 16:47 litest
-rw-r--r-- 1 root root    0 Dec  9 17:12 test1
lrwxrwxrwx 1 root root    5 Dec  9 17:13 test_soft -> test1

由於源文件test_soft本身就是一個軟鏈接文件,所以由它硬鏈接之后的文件test_hard1還是軟鏈接文件!
並且test_hard1文件的源文件指向並不是test_soft,而是最初的實體源文件test1!!
可以看出,test_soft和test_hard1同樣為指向test1源文件的軟鏈接文件,inode節點號都一樣(如下都是917511)
[root@ss-server test]# ln test_soft test_hard1
[root@ss-server test]# ls -li
total 4
917512 drwxr-xr-x 2 root root 4096 Dec  9 16:47 litest
917510 -rw-r--r-- 1 root root    0 Dec  9 17:12 test1
917511 lrwxrwxrwx 2 root root    5 Dec  9 17:13 test_hard1 -> test1
917511 lrwxrwxrwx 2 root root    5 Dec  9 17:13 test_soft -> test1

2)當源文件cp拷貝到另一個文件時,鏈接文件跟源文件內容保持一致,並不會跟源文件的備份文件不會保持一致!!
[root@ss-server test]# rm -f test_hard1
[root@ss-server test]# ll 
total 4
drwxr-xr-x 2 root root 4096 Dec  9 17:30 litest
-rw-r--r-- 1 root root    0 Dec  9 17:12 test1
lrwxrwxrwx 1 root root    5 Dec  9 17:27 test_soft -> test1
[root@ss-server test]# ln test1 test_hard
[root@ss-server test]# ls -l
total 4
drwxr-xr-x 2 root root 4096 Dec  9 17:30 litest
-rw-r--r-- 2 root root    0 Dec  9 17:12 test1                 #源文件
-rw-r--r-- 2 root root    0 Dec  9 17:12 test_hard             #硬連接文件
lrwxrwxrwx 1 root root    5 Dec  9 17:27 test_soft -> test1    #軟鏈接文件

[root@ss-server test]# echo "hello world,haha" > test1
[root@ss-server test]# cp test1 test_bak
[root@ss-server test]# ll -li
total 16
917512 drwxr-xr-x 2 root root 4096 Dec  9 17:30 litest
917510 -rw-r--r-- 2 root root   29 Dec  9 17:39 test1
917511 -rw-r--r-- 1 root root   17 Dec  9 17:37 test_bak
917510 -rw-r--r-- 2 root root   29 Dec  9 17:39 test_hard
917516 lrwxrwxrwx 1 root root    5 Dec  9 17:27 test_soft -> test1

[root@ss-server test]# cat test1 test_bak
hello world,haha
hello world,haha
[root@ss-server test]# cat test_soft test_hard
hello world,haha
hello world,haha
[root@ss-server test]# echo "heihei,nice" >> test1
[root@ss-server test]# cat test_soft test_hard 
hello world,haha
heihei,nice
hello world,haha
heihei,nice
[root@ss-server test]# cat test1
hello world,haha
heihei,nice
[root@ss-server test]# cat test_bak
hello world,haha

3)當源文件mv更名為另一個文件時,則鏈接文件跟源文件mv之后的文件內容保持一致!
[root@ss-server test]# mv test1 test_mv
[root@ss-server test]# echo "123456" >> test_mv

[root@ss-server test]# ls -li
total 16
917512 drwxr-xr-x 2 root root 4096 Dec  9 17:30 litest
917511 -rw-r--r-- 1 root root   17 Dec  9 17:37 test_bak
917510 -rw-r--r-- 2 root root   36 Dec  9 17:51 test_hard
917510 -rw-r--r-- 2 root root   36 Dec  9 17:51 test_mv
917516 lrwxrwxrwx 1 root root    5 Dec  9 17:27 test_soft -> test1

[root@ss-server test]# cat test_hard          #硬連接文件跟源文件mv更名后的文件保持一致(inode號和內容都保持一致)
hello world,haha
heihei,nice
123456

[root@ss-server test]# cat test_soft          #由於源文件更名,之前做的軟鏈接文件成為了死鏈文件!
cat: test_soft: No such file or directory

軟鏈接只認文件名,硬鏈接不僅認文件名,還認文件inode節點號。所以源文件mv更名后(文件mv前后,inode節點號不變),硬鏈接文件也跟着文件inode節點號過去了。

#############  需要注意  ################
硬鏈接限制 ["Invalid cross-device link錯誤"]:
1)不能跨文件系統。
2)只能在同一個分區建立數據關聯。
3)不能連接目錄。

軟鏈接可以跨文件系統,可以在不同分區創建軟鏈接文件!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM