前言
類似Windows系統,Linux系統在進行文件管理時,也會引入鏈接概念。而鏈接又分為軟鏈接和硬鏈接,兩種鏈接適用于不同場合、不同用途,各有優缺點。在介紹軟硬兩種鏈接之前,需要先引入inode的概念。
Inode:
系統在管理文件時,為了有序尋址,會將元數據(metadata)和用戶數據(userdata)分開存放。元數據是指文件各類附加屬性,如ls –l命令中顯示的文件類型、權限、屬主屬組、文件大小、修改時間以及文件名等信息;而用戶數據是指真實的對用戶有用的數據。Linux不同路徑下可以創建相同文件名稱的文件,對于計算機系統來說,識別二進制數字比直接的文件名更為快捷。所以Linux系統用不同的數字來標識不同的文件,而此數字就是inode號,即索引節點號(index node)。元數據中的inode才是系統識別文件的唯一標識符。
查看inode相關的命令:ls –i 、 stat 、 df –i
[root@Hisen /]# ls -i 393219 bin 524290 home 917506 media 1048581 opt 131074 selinux 393217 tmp 2 boot 786434 lib 12503 misc 1 proc 393220 srv 2 usr 4 dev 262146 lib64 917507 mnt 1048578 root 1 sys 2 var 1179649 etc 11 lost+found 2507 net 131075 sbin 131099 testdir
[root@Hisen /]# stat bin/ File: `bin/' Size: 4096 Blocks: 8 IO Block: 4096 directory Device: fd00h/64768d Inode: 393219 Links: 2 Access: (0555/dr-xr-xr-x) Uid: (0/root) Gid: (0/root) Access: 2016-10-19 11:58:26.863958830 +0800 Modify: 2016-10-18 09:07:21.360998536 +0800 Change: 2016-10-18 09:07:21.360998536 +0800
[root@Hisen /]# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/mapper/vg0-root 1310720 7105 1303615 1% / tmpfs 125596 1 125595 1% /dev/shm /dev/sda1 51200 38 51162 1% /boot /dev/mapper/vg0-usr 655360 100297 555063 16% /usr /dev/mapper/vg0-var 1310720 3150 1307570 1% /var /dev/sdb 1310720 12 1310708 1% /mnt/cdrom
一個節點是一個表項,其中包含有關文件信息的元數據,包括:
文件類型
權限
UID
GID
硬鏈接數
文件大小
時間戳
指針
其他數據
簡而言之,對于Linux系統來說,所有的目錄映射都是文件之間的inode號映射。
由于每個分區都有著自身的一套inode號,在執行類似于cp和mv的命令,會對目標文件的inode號有何影響?
cp和inode:
[root@Hisen ~]# cp /Hisen/testfile1 /tmp/ [root@Hisen ~]# ll -i /Hisen/testfile1 /tmp/testfile1 917512 -rw-r--r-- 1 root root 0 Oct 19 12:51 /Hisen/testfile1 393361 -rw-r--r-- 1 root root 0 Oct 19 13:19 /tmp/testfile1
cp命令復制文件的原理:分配一個空閑的inode號,在inode表中生成新條目在目錄中創建一個目錄項,將名稱與inode編號關聯拷貝數據生成新的文件。
mv和inode:
①如果mv命令的目標和源在相同的文件系統
[root@Hisen ~]# rm -rf /tmp/testfile1 [root@Hisen ~]# ll -i /Hisen/testfile1 917512 -rw-r--r-- 1 root root 0 Oct 19 12:51 /Hisen/testfile1 [root@Hisen ~]# mv /Hisen/testfile1 /tmp/ [root@Hisen ~]# ll -i /tmp/testfile1 917512 -rw-r--r-- 1 root root 0 Oct 19 12:51 /tmp/testfile1
用新的文件名創建對應新的目錄項,刪除舊目錄條目對應的舊的文件名,不影響inode表(除時間戳)或磁盤上的數據位置:沒有數據被移動!
②如果目標和源在一個不同的文件系統
將sdb硬盤掛載至/mnt/cdrom下:
[root@Hisen ~]# mount /dev/sdb on /mnt/cdrom type ext4 (rw)
/Hisen/testfile1的原始inode:
[root@Hisen ~]# ll -i /Hisen/testfile1 917512 -rw-r--r-- 1 root root 0 Oct 19 12:51 /Hisen/testfile1
將/Hisen/testfile1移動至不同分區的/mnt/cdrom下:
[root@Hisen ~]# mv /Hisen/testfile1 /mnt/cdrom/ [root@Hisen ~]# ll -i /mnt/cdrom/testfile1 12 -rw-r--r-- 1 root root 0 Oct 19 12:51 /mnt/cdrom/testfile1
rm和inode:
刪除文件其實就是釋放inode號,而之前的用戶數據則依然保存在硬盤內部,只不過系統會將沒有inode號的數據標記為空閑狀態。
硬鏈接
如果用人來形容的話,inode號就相當于身份證號碼,在同分區內唯一標識。而硬鏈接就相當于將我們重新取個名字,但在本質上,都是我們自己本身。
命令:ln filename [linkname ]
用ls –l命令可以查看當前文件的硬鏈接數:
[root@Hisen Hisen]# ll -di /Hisen/ 917509 drwxr-xr-x 3 root root 4096 Oct 19 13:35 /Hisen/
其中數字3就代表當前目錄的硬鏈接數。那么這3次硬鏈接又是從何而來?
/Hisen/目錄本身inode號:
[root@Hisen ~]# ll -id /Hisen/ 917509 drwxr-xr-x 3 root root 4096 Oct 19 13:35 /Hisen/
/Hisen/目錄下所有子文件inode信息:
[root@Hisen ~]# ll -ai /Hisen/ 917509 drwxr-xr-x 3 root root 4096 Oct 19 13:35 . 2 dr-xr-xr-x. 26 root root 524288 Oct 19 12:50 .. 917511 drwxr-xr-x 2 root root 4096 Oct 19 12:52 testdir1
子目錄/Hisen/testdir1/目錄下子文件inode信息:
[root@Hisen ~]# ll -ai /Hisen/testdir1/ 917511 drwxr-xr-x 2 root root 4096 Oct 19 12:52 . 917509 drwxr-xr-x 3 root root 4096 Oct 19 13:35 .. 917513 -rw-r--r-- 1 root root 0 Oct 19 12:52 testfile2
可以看出:/Hisen/自身目錄下有·和··的隱藏目錄,而·目錄的inode號跟自身相同,··目錄的inode號跟父目錄相同,而/Hisen/testdir1/目錄下··的inode號又跟/Hisen/目錄相同。
因此默認的目錄下都會出現·和··兩個隱藏目錄項,其中·代表當前目錄的硬鏈接,··代表父目錄對當前目錄的硬鏈接,所以每個目錄文件都至少有2次硬鏈接。由于當前目錄的子目錄也會對父目錄進行硬鏈接,所以每個目錄的硬鏈接數等于2加上子目錄數。而在/Hisen/目錄下,有一個testdir1的目錄文件,所以硬鏈接數為3。
既然我們知道目錄的硬鏈接數從何而來,那么接下來再看看文件的硬鏈接數吧。
將/Hisen/testdir1/下的testfile2硬鏈接至/tmp/下,鏈接名為link01:
[root@Hisen ~]# ln /Hisen/testdir1/testfile2 /tmp/link01 [root@Hisen ~]# ll -i /Hisen/testdir1/testfile2 /tmp/link01 917513 -rw-r--r-- 2 root root 6 Oct 19 14:30 /Hisen/testdir1/testfile2 917513 -rw-r--r-- 2 root root 6 Oct 19 14:30 /tmp/link01
上例可知硬鏈接一次文件,該文件的硬鏈接次數增加1。
/Hisen/testdir1/testfile2文件中只保存‘Hisen’五個英文字符,接下來我們刪除/Hisen/testdir1/testfile2,看看link01文件是否能正常訪問。
[root@Hisen ~]# rm -rf /Hisen/testdir1/testfile2 [root@Hisen ~]# cat /tmp/link01 Hisen
由上可知,硬鏈接映射同一個inode號,刪除其中一個文件名,并不影響其他文件名的使用。多個硬鏈接名之間并無任何依賴關系存在。
如果將文件跨分區進行硬鏈接,會出現設備結果?
[root@Hisen ~]# ln /Hisen/testdir1/testfile2 /mnt/cdrom/ ln:creating hard link `/mnt/cdrom/testfile2' => `/Hisen/testdir1/testfile2': Invalid cross-device link
上面例子提示,無法跨設備進行硬鏈接。是因為,每個分區都會有自己的inode號,不同的分區下相同的inode號很可能有不同的用途。
關于路徑,硬鏈接既可以使用當前絕對路徑(見上例),也可以使用相對路徑。其中相對路徑又分為:相對于當前目錄和相對于鏈接目標文件的路徑。
相對于當前路徑的硬鏈接:
[root@Hisen testdir1]# ln testfile2 /tmp/link02 [root@Hisen testdir1]# ll -i testfile2 /tmp/link02 917513 -rw-r--r-- 2 root root 6 Oct 19 14:30 testfile2 917513 -rw-r--r-- 2 root root 6 Oct 19 14:30 /tmp/link02
相對于鏈接目標文件的硬鏈接:
[root@Hisen ~]# ln ../Hisen/testdir1/testfile2 /tmp/link03 [root@Hisen ~]# ll -i /Hisen/testdir1/testfile2 /tmp/link03 917513 -rw-r--r-- 3 root root 6 Oct 19 14:30 /Hisen/testdir1/testfile2 917513 -rw-r--r-- 3 root root 6 Oct 19 14:30 /tmp/link03
軟鏈接
軟鏈接就相當于windows系統的快捷方式,它對被鏈接文件的依賴性非常強。軟鏈接是一個全新的文件,被分配了一個不同于被鏈接文件的inode號,也就相當于軟鏈接文件中保存的就是被鏈接文件的路徑。如果按照存儲中的路徑找不到跟被鏈接文件相同文件名的文件,那么此軟鏈接將會失效。言外之意就是,軟鏈接并不關心被鏈接文件的具體內容,只要按照路徑查找能匹配到相同文件名就好。軟鏈接的優勢在于它能跨分區跨設備甚至跨網絡。
命令:ln -s filename [linkname]
[root@Hisen ~]# ln -s /Hisen/testdir1/testfile2 /tmp/link04 [root@Hisen ~]# ll -i /Hisen/testdir1/testfile2 /tmp/link04 917513 -rw-r--r-- 1 root root 6 Oct 19 14:30 /Hisen/testdir1/testfile2 393362 lrwxrwxrwx 1 root root 25 Oct 19 15:16 /tmp/link04 -> /Hisen/testdir1/testfile2
由上例可看出,軟鏈接與實際文件的差別挺大的。/tmp/link04文件有25字節大小,具體內容為真實文件的路徑,不信自己數一數。
將/Hisen/testdir1/testfile2文件刪除后,軟鏈接就呈現失效的狀態。
那么在/Hisen/testdir1/下新建一個文件名為testfile2的文件會有什么效果呢?
軟鏈接又恢復正常狀態,印證了軟鏈接并不關心文件里的具體內容。
另外,硬鏈接不能針對目錄,那么軟鏈接能否針對目錄呢?
上圖已經證實,軟鏈接是可以針對于目錄做鏈接。
我們已經知道,硬鏈接是無法跨設備跨分區的,那么軟鏈接跨分區的效果如何?
正如所料到的那樣,一切正常,證明軟鏈接是可以跨設備跨分區的。
接下來,關于鏈接路徑的寫法,軟鏈接和硬鏈接有著比較大的區別:
①當前目錄下:
②絕對路徑:
③相對于被鏈接文件路徑的相對路徑:
綜上,軟鏈接支持絕對路徑和被鏈接文件路徑相對的路徑鏈接,但是由于在開發環境中考慮到可移植性,最好寫成相對路徑。
總結
通過上面兩節對軟鏈接和硬鏈接的介紹后,相信區別已經顯而易見了。不過還是需要好好的總結一下:
1、命令格式:
硬鏈接:ln filename [linkname ]
軟鏈接:ln -s filename [linkname]
2、inode:
硬鏈接:與被鏈接目標文件相同,創建時鏈接數遞增;
軟鏈接:與被鏈接目標文件不同,創建時目標文件inode引用計數不變。
3、依賴性:
硬鏈接:鏈接之后,與原名稱無關,直接指向真實的數據。刪除原文件名,不影響新文件名使用數據;
軟鏈接:鏈接之后,需要能在保存的路徑下匹配到相同的文件名。刪除原文件名,則鏈接失效。
4、存儲數據:
硬鏈接:直接指向真實的數據,相同的inode號;
軟鏈接:存儲的是被鏈接文件的路徑。
5、跨設備跨分區:
硬鏈接:不可以;
軟鏈接:可以。
6、鏈接路徑:
硬鏈接:可當前、可絕對、可相對被鏈接文件路徑;
軟鏈接:不可當前、可絕對,可相對被鏈接文件路徑。
7、鏈接對象:
硬鏈接:可文件、不可目錄;
軟鏈接:可文件、可目錄。
原創文章,作者:Hisen,如若轉載,請注明出處:http://www.www58058.com/53158