Linux下的鏈接文件詳解
ln命令
我們用ln命令創(chuàng)建硬鏈接或者軟鏈接。其語法為:
ln [options] file link
此命令的第一種形式會創(chuàng)建一個指向file的新的鏈接,其中options選項(xiàng),我們只記住一個就行,-s表示創(chuàng)建軟鏈接,而默認(rèn)會創(chuàng)建硬鏈接。例如:
# ln -s /usr/src/linux-2.6.32 /usr/src/linux
這里,我們創(chuàng)建了一個符號鏈接/usr/src/linux,指向真實(shí)的Linux源代碼目錄/usr/src/linux-2.6.32。
我們再舉一個例子,演示一下軟鏈接與硬鏈接的區(qū)別,我們創(chuàng)建一個myfile文件,然后再創(chuàng)建一個指向該文件的軟鏈接myslink和硬鏈接myhlink:
$ $ echo "an example." > myfile $ ln -s myfile myslink $ ls myfile myhlink
使用stat檢查前述文件:
$ stat my* File: `myfile' Size: 12 Blocks: 8 IO Block: 4096 regular file Device: fd00h/64768d Inode: 11552 Links: 2 Access: (0664/-rw-rw-r--) Uid: ( 500/ wjm) Gid: ( 500/ wjm) Access: 2016-08-10 03:59:54.421017669 +0800 Modify: 2016-08-10 03:59:54.421017669 +0800 Change: 2016-08-10 04:00:08.689000105 +0800 File: `myhlink' Size: 12 Blocks: 8 IO Block: 4096 regular file Device: fd00h/64768d Inode: 11552 Links: 2 Access: (0664/-rw-rw-r--) Uid: ( 500/ wjm) Gid: ( 500/ wjm) Access: 2016-08-10 03:59:54.421017669 +0800 Modify: 2016-08-10 03:59:54.421017669 +0800 Change: 2016-08-10 04:00:08.689000105 +0800 File: `myslink' -> `myfile' Size: 6 Blocks: 0 IO Block: 4096 symbolic link Device: fd00h/64768d Inode: 11553 Links: 1 Access: (0777/lrwxrwxrwx) Uid: ( 500/ wjm) Gid: ( 500/ wjm) Access: 2016-08-10 04:00:03.784997923 +0800 Modify: 2016-08-10 04:00:03.784997923 +0800 Change: 2016-08-10 04:00:03.784997923 +0800
仔細(xì)觀察myfile和myhlink,發(fā)現(xiàn)它們指向同一個inode(inode號同為11552)。硬鏈接數(shù)(Links字段)同為2,這表示有兩個目錄項(xiàng)指向該inode,每增加一個硬鏈接Links字段值就會增加1。而myslink文件,我們發(fā)現(xiàn)它的inode號與前兩個不同,其訪問權(quán)限為0777。我們刪除myhlink這個硬鏈接,看看會出現(xiàn)什么變化?這次我們用ls -il命令來查看:
$ rm myfile $ ll -li total 4 11552 -rw-rw-r-- 1 wjm wjm 12 Aug 10 03:59 myhlink 11553 lrwxrwxrwx 1 wjm wjm 6 Aug 10 04:00 myslink -> myfile $ cat myhlink an example. $ cat myslink cat: myslink: No such file or directory
ls命令的-i選項(xiàng)也可以輸出文件的inode號。輸出信息的第三列為硬鏈接數(shù),我們發(fā)現(xiàn)刪除了myfile文件后,myhlink的硬鏈接數(shù)已經(jīng)由2變?yōu)?了,但是原myfile文件的數(shù)據(jù)依然可以通過myhlink這個硬鏈接訪問,因?yàn)橛叉溄邮峭ㄟ^文件的inode號來訪問文件數(shù)據(jù)的。然而通過myslink軟鏈接卻無法再訪問原myfile文件的數(shù)據(jù)了,因?yàn)檐涙溄訉?shí)質(zhì)上是一個指向目標(biāo)文件的全路徑,這個路徑中任何一個環(huán)節(jié)斷裂,都會使這個軟鏈接失效。
追隨鏈接
自從了軟連接,當(dāng)你要備份、復(fù)制或者移動目錄或者文件時候,會出現(xiàn)是否要“追隨鏈接”的問題。如果是,則會復(fù)制鏈接所指向的對象;如果不是,則僅僅操作鏈接本身。
通常如tar或cp之類的命令工具會給出是否追隨鏈接的選項(xiàng)。如cp,你可以使用-L選項(xiàng)表示追隨鏈接(復(fù)制鏈接所指向的目標(biāo)),或者用-P表示不追隨鏈接(復(fù)制鏈接本身)。如下例:
$ mkdir dir1 $ ln -s /tmp/a.txt dir1/slink $ cp -rL dir1 dir2 $ ls -l dir2 total 0 -rw-rw-r-- 1 wjm wjm 0 Aug 6 17:02 slink
這里我們在dir1目錄下創(chuàng)建了一個軟鏈接,當(dāng)用-L選項(xiàng)將其復(fù)制到dir2目錄下時,我們看到dir2目錄下的slink現(xiàn)在成為一個普通文件。如果使用-P選項(xiàng)(保存鏈接)復(fù)制,則復(fù)制后的文件依然是一個軟鏈接:
$ cp -rP dir1 dir3 $ ls -l dir3 total 0 lrwxrwxrwx 1 wjm wjm 10 Aug 6 17:07 slink -> /tmp/a.txt
假如沒有明確指定-L或者-P選項(xiàng),則cp的默認(rèn)行為將隨版本而定。
目錄的硬鏈接
前文提到過,無法對一個目錄創(chuàng)建硬鏈接。但其實(shí)目錄是存在硬鏈接的,只是這個硬鏈接是系統(tǒng)自動創(chuàng)建的,而我們不能手動創(chuàng)建。當(dāng)我們用mkdir創(chuàng)建一個空目錄時,會發(fā)現(xiàn)這個目錄的硬鏈接數(shù)為2,例如:
$ ls -dl ~ drwx------. 6 wjm wjm 4096 Aug 10 04:25 /home/wjm $ cd ~ $ mkdir mydir $ ls -dli ~ 8605 drwx------. 7 wjm wjm 4096 Aug 10 04:25 /home/wjm $ ls -dli mydir 11556 drwxrwxr-x 2 wjm wjm 4096 Aug 10 04:25 mydir
原先/home/wjm目錄的硬鏈接數(shù)量為6,當(dāng)在/home/wjm下創(chuàng)建了一個空目錄mydir后,它的硬鏈接數(shù)量變成了7,而這個空目錄mydir的硬鏈接數(shù)為2。這是為什么呢?原因是任何一個目錄下,都有兩個隱藏的硬鏈接:
ls -ali mydir total 8 11556 drwxrwxr-x 2 wjm wjm 4096 Aug 10 04:25 . 8605 drwx------. 7 wjm wjm 4096 Aug 10 04:25 ..
我們看到mydir目錄下有兩個隱藏的硬鏈接,使用ls的-a選項(xiàng)才能使其列出來。其中一個硬鏈接是“.”,指向的inode號為11556,就是mydir這個目錄本身的inode號;另一個是“..”,通過inode號我們發(fā)現(xiàn)它指向了其父目錄/home/wjm。因此,當(dāng)創(chuàng)建了空目錄mydir后,mydir的硬鏈接數(shù)為2,而其父目錄的硬鏈接數(shù)加1。所以一個目錄的硬鏈接數(shù)=其子目錄數(shù)+2。
這種硬鏈接是系統(tǒng)自動為我們創(chuàng)建的,而當(dāng)你試圖手動創(chuàng)建一個指向目錄的硬鏈接時,系統(tǒng)一定會報錯阻止你這樣做。為什么呢?
其實(shí)在UNIX操作系統(tǒng)的歷史上,對目錄創(chuàng)建硬鏈接曾經(jīng)是允許的。但人們發(fā)現(xiàn),這樣做會出現(xiàn)很多問題,尤其是一些對目錄樹進(jìn)行遍歷操作的如fsck、find等命令無法正確執(zhí)行。在《Unix高級環(huán)境編程》中提到作者Steven在自己的系統(tǒng)上做過實(shí)驗(yàn),結(jié)果是:創(chuàng)建目錄硬鏈接后,文件系統(tǒng)變得錯誤百出。因?yàn)檫@樣做會破壞文件系統(tǒng)的樹形結(jié)構(gòu),可能會使目錄之間出現(xiàn)環(huán)。例如:
$ ln ~ ~/mydir/myhdir_link ln: `/home/wjm': hard link not allowed for directory $ ln -s ~ ~/mydir/myhdir_link
這里第一條命令我們試圖在mydir目錄下創(chuàng)建一個硬鏈接指向其父目錄,然而失敗了。因?yàn)檫@使得/home/wjm和/home/wjm/mydir兩個目錄之間形成一個環(huán),我們無法再區(qū)分這兩者誰是父目錄誰是子目錄了。然而第二條命令創(chuàng)建一個指向其父目錄的軟鏈接卻可以成功,難道這樣不是同樣形成了一個環(huán)嗎?
為什么軟鏈接可以指向目錄而硬鏈接不行呢?根本原因在于軟鏈接實(shí)質(zhì)上是一個文件,而硬鏈接實(shí)質(zhì)上是一個目錄項(xiàng)(dentry)。在linux系統(tǒng)中,每個文件(目錄也是文件,軟鏈接也是文件)都對應(yīng)著一個inode結(jié)構(gòu),其中inode數(shù)據(jù)結(jié)構(gòu)中包含了文件類型(目錄,普通文件,符號連接文件等等)的信息,也就是說操作系統(tǒng)在遍歷目錄時可以判斷出符號連接。既然可以判斷出符號連接當(dāng)然就可以采取一些措施來防范進(jìn)入死循環(huán)了,系統(tǒng)在連續(xù)遇到8個符號連接后就停止遍歷,這就是為什么對目錄符號連接不會進(jìn)入死循環(huán)的原因了。而“硬鏈接”本質(zhì)上是“目錄項(xiàng)”的同義詞。當(dāng)一個目標(biāo)第一次被創(chuàng)建,就會為它創(chuàng)建一個目錄項(xiàng),這其實(shí)就是硬鏈接。大多數(shù)人常常把“硬鏈接”聯(lián)想成為一個已有的對象創(chuàng)建一個額外的目錄項(xiàng),但其實(shí)是原來的目錄項(xiàng)沒有任何特殊,所有的硬鏈接都是平等的,所以Linux內(nèi)核沒有方法能識別出哪個是“原文件”哪個是“硬鏈接”。這樣對于由于目錄硬鏈接而形成的環(huán)就無法進(jìn)行合適的處理。
但是根目錄是一個特例。我們觀察:
$ ls -dli /
2 dr-xr-xr-x. 22 root root 4096 Aug 10 00:50 /
$ ls -ali /
total 102
2 dr-xr-xr-x. 22 root root 4096 Aug 10 00:50 .
2 dr-xr-xr-x. 22 root root 4096 Aug 10 00:50 ..
... ...
可見這里根目錄的inode號為2,而且根目錄下的指向其父目錄的隱藏硬鏈接(..)也指向了自身。
相關(guān)文章
linux centos 系統(tǒng)中文模式設(shè)置方法
怎么設(shè)置Linux系統(tǒng)中文語言?在我們使用CentOS的使用都喜歡使用中文語言,本文小編將為大家具體的介紹centos 系統(tǒng)中文默認(rèn)語言修改的方法2016-11-23- Ping是Windows、Unix和Linux系統(tǒng)下的一個命令,也是通信協(xié)議,是TCP/IP協(xié)議的一部分,還可以檢查網(wǎng)絡(luò)是否連通,更好的幫助我們分析和判定網(wǎng)絡(luò)故障等問題2016-11-22
linux系統(tǒng)下Centos中"vim配置"到底有多強(qiáng)大
當(dāng)我們在linux系統(tǒng)中使用vim編輯器時,總感覺vim編輯器的界面不是太美觀,不能讓用戶使用的舒服,不僅僅頁面設(shè)置不習(xí)慣,沒有顯示的行號,也沒有自動的縮進(jìn),頁面的背景也2016-11-22- 這篇文章主要介紹了Linux刪除重復(fù)行的代碼,需要的朋友可以參考下2016-11-25
- 這篇文章主要介紹了Linux 統(tǒng)計代碼行數(shù)的代碼,需要的朋友可以參考下2016-11-21
- 在Linux下的磁盤內(nèi)容作為子目錄形式出現(xiàn)的,可移動介質(zhì)的內(nèi)容不會自動出現(xiàn)在這些子目錄中,因此需要我們通過掛載驅(qū)動器來實(shí)現(xiàn)2016-11-21
- 這篇文章主要介紹了Linux date日期格式及加減運(yùn)算,需要的朋友可以參考下2016-11-21
- 這篇文章主要介紹了Linux 刪除文本中的重復(fù)行的方法,需要的朋友可以參考下2016-11-21
Linux下which、whereis、locate、find 區(qū)別
這篇文章主要介紹了Linux下which、whereis、locate、find 區(qū)別,需要的朋友可以參考下2016-11-21- Linux中編譯CoreCLR,很多用戶不知道如何在CentOS上編譯并安裝Clang,本文將詳細(xì)介紹具體的步驟,希望可以幫助到大家2016-11-18

