Linux中硬連結和軟連接配接的介紹
1 硬連結
硬連結,也即“hard link”,其本質為現有檔案的另一個名字,是以硬連結和原檔案是無法區分的。從技術上講,它們共享相同的inode,而inode幾乎包含檔案的所有資訊,包括指向資料塊的直接/間接指針。
1.1 硬連結的建立
建立硬連結的指令為
ln [option] /path1/TARGET /path2/LINK_FILE
.其中
/path1/TARGET
為原檔案的路徑,
/path2/LINK_FILE
為即将建立的連結檔案的路徑及檔案名。
[[email protected] app]#ll -i all
67 -rw-r--r--. 1 root root 24 Jul 22 10:48 all
[[email protected] app]#ln all all-link
[[email protected] app]#ls
all all-link
1.2 硬連結的特性
- 檔案有相同的 inode 及 data block
利用
ll -i file_name
可以檢視檔案的節點(inode)編号以及連接配接數。原檔案all在建立硬連結之前節點編号為67,連結數為1。在目前工作目錄建立連結檔案all-link後,連結檔案all-link的節點編号也是67,而此時all和all-link的連接配接數都變成2。由此可見,建立硬連結後,節點編号不變,連接配接數+1 。
使用指令
stat
檢視兩個檔案的中繼資料也都完全相同。
[[email protected] app]#ll -i !*
ll -i all all-link
-rw-r--r--. 2 root root 24 Jul 22 10:48 all
-rw-r--r--. 2 root root 24 Jul 22 10:48 all-link
[[email protected] app]#stat *
File: ‘all’
Size: Blocks: IO Block: regular file
Device: h/d Inode: Links:
Access: (/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:etc_runtime_t:s0
Access: -- :: +
Modify: -- :: +
Change: -- :: +
Birth: -
File: ‘all-link’
Size: Blocks: IO Block: regular file
Device: h/d Inode: Links:
Access: (/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:etc_runtime_t:s0
Access: -- :: +
Modify: -- :: +
Change: -- :: +
Birth: -
- 隻能對已存在的檔案進行建立
如果連結檔案的命名與已存在檔案重複,則連結檔案不會被建立,同時輸出報錯資訊:
[[email protected] app]#ln aa aa-link
ln: failed to access ‘aa’: No such file or directory
[[email protected] app]#ln all all-link
ln: failed to create hard link ‘all-link’: File exists
- 删除一個硬連結檔案并不影響其他有相同inode号的檔案
既然硬連結和原檔案本質是同一個,那麼我删除其中一個檔案,會對另一個檔案有影響嗎?
首先嘗試删除建立的連結檔案:
[[email protected] app]#cat all
Welcome to Linux World!
[[email protected] app]#ll -i *
67 -rw-r--r--. 2 root root 24 Jul 22 10:48 all
67 -rw-r--r--. 2 root root 24 Jul 22 10:48 all-link
[[email protected] app]#rm -f all-link
[[email protected] app]#cat all
Welcome to Linux World!
[[email protected] app]#ll -a *
67 -rw-r--r--. 1 root root 24 Jul 22 10:48 all
删除連結檔案後,原檔案的連接配接數再次回到1,其他中繼資料及資料塊本身沒有任何變化。
現在重新建立硬連結,并删除原檔案:
[[email protected] app]#ln all all-link
[[email protected] app]#cat all-link
Welcome to Linux World!
[[email protected] app]#ll -i *
67 -rw-r--r--. 2 root root 24 Jul 22 10:48 all
67 -rw-r--r--. 2 root root 24 Jul 22 10:48 all-link
[[email protected] app]#rm -f all
[[email protected] app]#cat all-link
Welcome to Linux World!
[[email protected] app]#ll -i *
67 -rw-r--r--. 1 root root 24 Jul 22 10:48 all-link
由此可見,硬連結和原檔案的删除操作互相之間沒有影響(連接配接數會減少)。
- 不能交叉檔案系統(分區)進行硬連結的建立
在我的實驗系統中,”/tmp”和”/app”分别在兩個獨立的分區
[root@Centos7T app]#df -h /tmp /app
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 50G 3.7G 47G 8% /
/dev/sda5 G M G % /app
現在對
/app
下的檔案all嘗試建立兩個硬連結,一個位于/app,一個位于/tmp
[root@Centos7T app]#ll -i *
-rw-r--r--. root root Jul : all
[root@Centos7T app]#ln all all-link
[root@Centos7T app]#ll -i *
-rw-r--r--. root root Jul : all
-rw-r--r--. root root Jul : all-link
[root@Centos7T app]#ln all /tmp/all-link
ln: failed to create hard link ‘/tmp/all-link’ => ‘all’: Invalid cross-device link
結果顯示位于/app下的硬連結建立成功,而位于/tmp下的硬連結無法建立并報錯“Invalid cross-device link”
- 不能對目錄進行建立,隻可對檔案建立
[root@Centos7T app]#mkdir test
[root@Centos7T app]#ll -id test/
drwxr-xr-x. root root Jul :08 test/
[root@Centos7T app]#ln -d test/ test-link/
ln: target ‘test-link/’ is not a directory: No such file or directory
[root@Centos7T app]#mkdir test-link/
[root@Centos7T app]#ln test/ test-link/
ln: ‘test/’: hard link not allowed for directory
在實驗中,我們對已有目錄test在目前目錄建立硬連結test-link,直接報錯連結目錄不存在(target ‘test-link/’ is not a directory: No such file or directory)。于是建立目錄test-link,重新建立硬連結,還是報錯不允許給目錄建立硬連結(hard link not allowed for directory)。
至此,有關硬連結的5條特性均用代碼完成驗證。
2 軟連結
軟連結,也稱為符号連結,即“symbolic links/soft links”,是一個通過名稱指向另一個不同檔案的特殊的檔案類型,是一個單獨的檔案,有着不同于原檔案(目标檔案)的屬性,相當于Windows系統中的快捷方式。當對軟連結進行大多數操作(包括打開、讀取、寫入等等)時,系統核心會自動在軟連結的目标檔案上執行;但某些操作,例如删除,會直接對連結檔案本身操作。
2.1 軟連結的建立
建立軟連結的指令為
ln -s /path1/TARGET /path2/LINK_FILE
.其中
/path1/TARGET
為目标檔案的路徑,
/path2/LINK_FILE
為即将建立的連結檔案的路徑。
[[email protected] app]#ll -i *
70 -rw-r--r--. 1 root root 24 Jul 22 19:51 soft
[[email protected] app]#ln -s soft soft-link
2.2 軟連結的特性
- 軟連結和目标檔案不是同一個檔案,節點号不同
擷取目标檔案和連結檔案相關屬性資訊
[[email protected] app]#ll -i *
70 -rw-r--r--. 1 root root 24 Jul 22 19:51 soft
67 lrwxrwxrwx. 1 root root 4 Jul 22 19:51 soft-link -> soft
注意觀察軟連接配接檔案soft-link的各項屬性與目标檔案soft的差別,軟連結檔案類型為連結檔案,目标檔案類型為普通檔案,另外,軟連結的節點編号、權限、大小等屬性與目标檔案均不相同。同時,建立軟連結後,目标檔案的連接配接數并對應不增加。顯然,軟連結檔案和目标檔案是兩個不同的檔案。但是,對軟連結檔案的讀取、寫入等操作都自動轉到對目标檔案的操作(注意删除操作除外)。
[root@Centos7T app]#cat soft-link
Welcome to Linux World!
[root@Centos7T app]#echo 'Hello World!' >> soft-link
[root@Centos7T app]#cat soft
Welcome to Linux World!
Hello World!
- 可對目錄建立軟連結
前面提到不可對目錄建立硬連結,但是可以對目錄建立軟連結。
[[email protected] app]#ll -id test
69 drwxr-xr-x. 2 root root 6 Jul 22 20:57 test
[[email protected] app]#ln -s test test-link
[[email protected] app]#ll -id te*
69 drwxr-xr-x. 2 root root 6 Jul 22 20:57 test
70 lrwxrwxrwx. 1 root root 4 Jul 22 20:57 test-link -> test
軟連結的建立還有個很重要的特性,它可以對不存在的檔案、目錄進行建立。當然,由于目标檔案/目錄不存在,此刻我們還不能通過軟連結通路目标,這樣的軟連結稱為“死鍊”。 死鍊在終端中會閃爍顯示出來。
[[email protected] app]#ln -s unknown unknown-link
[[email protected] app]#ll -i un*
71 lrwxrwxrwx. 1 root root 7 Jul 22 21:00 unknown-link -> unknown
當然,如果我們在目前目錄建立一個名為unknown的檔案夾,那麼軟連結unknown-link會立即指向unknown檔案夾,我們也可通過通路unknown-link來通路unknown。如果我們建立的是一個名為unknown的檔案,并寫入内容。那麼unknown-link也會立即指向該檔案,我們可以通過對unknown-link的讀取、寫入等操作實際操作unknown檔案。即,可以針對不存在的檔案或目錄建立軟連結。
[[email protected] app]#ln -s unknown unknown-link
[[email protected] app]#ll -i un*
71 lrwxrwxrwx. 1 root root 7 Jul 22 21:00 unknown-link -> unknown
[[email protected] app]#mkdir unknown
[[email protected] app]#ll -id un*
33555328 drwxr-xr-x. 2 root root 6 Jul 22 21:13 unknown
71 lrwxrwxrwx. 1 root root 7 Jul 22 21:00 unknown-link -> unknown
删除unknown檔案夾,重新建立unknown檔案,并寫入内容
[root@Centos7T app]#rm -rf unknown
[root@Centos7T app]#ll -i un*
lrwxrwxrwx. root root Jul : unknown-link -> unknown
[root@Centos7T app]#echo 'Welcome to Linux World!' > unknown
[root@Centos7T app]#ll -i un*
-rw-r--r--. root root Jul : unknown
lrwxrwxrwx. root root Jul : unknown-link -> unknown
[root@Centos7T app]#cat unknown-link
Welcome to Linux World!
- 目标檔案的删除操作會影響軟連結檔案
删除軟連結
[[email protected] app]#ll -id *
68 -rw-r--r--. 1 root root 37 Jul 22 20:42 soft
67 lrwxrwxrwx. 1 root root 4 Jul 22 20:34 soft-link -> soft
69 drwxr-xr-x. 2 root root 6 Jul 22 20:57 test
70 lrwxrwxrwx. 1 root root 4 Jul 22 20:57 test-link -> test
[[email protected] app]#
[[email protected] app]#rm -rf soft-link test-link
[[email protected] app]#ll -id *
68 -rw-r--r--. 1 root root 37 Jul 22 20:42 soft
69 drwxr-xr-x. 2 root root 6 Jul 22 20:57 test
删除目标檔案
[root@Centos7T app]#ll -id *
-rw-r--r--. root root Jul : soft
lrwxrwxrwx. root root Jul : soft-link -> soft
drwxr-xr-x. root root Jul : test
lrwxrwxrwx. root root Jul : test-link -> test
[root@Centos7T app]#rm -rf soft test
[root@Centos7T app]#ll -id *
lrwxrwxrwx. root root Jul : soft-link -> soft
lrwxrwxrwx. root root Jul : test-link -> test
[root@Centos7T app]#cat soft-link
cat: soft-link: No such file or directory
[root@Centos7T app]#cd test-link
-bash: cd: test-link: No such file or directory
上述兩段代碼可以看出,當連結檔案被删除時,不會對目标檔案産生影響;當删除目标檔案/目錄時,由于失去了目标指向,軟連結會失效,變成死鍊。
- 能交叉檔案系統(分區)進行軟連結的建立
給
/app/soft
分别在兩個分區
/app
和
/tmp
路徑下建立兩個軟連結
[root@Centos7T app]#df -h /app /tmp
Filesystem Size Used Avail Use% Mounted on
/dev/sda5 G M G % /app
/dev/sda2 G G G % /
[root@Centos7T app]#ln -s /app/soft /app/soft-link
[root@Centos7T app]#ln -s /app/soft /tmp/soft-link
[root@Centos7T app]#ll -i /app/soft-link /tmp/soft-link
lrwxrwxrwx. root root Jul : /app/soft-link -> /app/soft
lrwxrwxrwx. root root Jul : /tmp/soft-link -> /app/soft
[root@Centos7T app]#cat /app/soft-link /tmp/soft-link
Welcome to Linux World!
Welcome to Linux World!
跨分區的軟連結建立成功。
- 軟連結中目标檔案相對路徑的使用
在上面建立
/tmp/soft-link
時我犯了個錯誤,導緻軟連結建立成功,但是提示是死鍊,無法指向
/app/soft
。這個錯誤我再此複現:
[root@Centos7T app]#ln -s soft /tmp/soft-link
[root@Centos7T app]#ll -i /tmp/soft-link
lrwxrwxrwx. root root Jul : /tmp/soft-link -> soft
[root@Centos7T app]#cat /tmp/soft-link
cat: /tmp/soft-link: No such file or directory
這個錯誤實際上是由建立軟連結時錯誤的使用目标檔案的相對路徑導緻的。觀察
/tmp/soft-link -> soft
,可以發現,軟連結
/tmp/soft-link
實際指向的不是
/app/soft
,而是
/tmp/soft
,而在
/tmp
中不存在soft檔案,故成為死鍊。實際上,即便恰好存在,軟連結不是死鍊,但還是與我們的操作原意不符。
建立軟連結時,目标檔案的相對路徑應該是相對于連結檔案的相對位置,而非相對于目前工作目錄的相對位置
[root@Centos7T app]#ll -i soft
-rw-r--r--. root root Jul : soft
[root@Centos7T app]#ln -s soft /home/geoffrey/Desktop/soft-link1
[root@Centos7T app]#ln -s ../../../app/soft /home/geoffrey/Desktop/soft-link2
[root@Centos7T app]#cd /home/geoffrey/Desktop/
[root@Centos7T Desktop]#ll -i so*
lrwxrwxrwx. root root Jul : soft-link1 -> soft
lrwxrwxrwx. root root Jul : soft-link2 -> ../../../app/soft
[root@Centos7T Desktop]#cat soft-link1
cat: soft-link1: No such file or directory
[root@Centos7T Desktop]#cat soft-link2
Welcome to Linux World!
軟連結soft-link1實際上是死鍊,其指向的soft在
Desktop
找不到;soft-link2正常,其指向的
../../../app/soft
最終指向了
/app/soft
。當然,目标檔案使用絕對路徑,就不會有這樣的錯誤了。