鏈接的“軟”與“硬”

前言

    類似Windows系統,Linux系統在進行文件管理時,也會引入鏈接概念。而鏈接又分為軟鏈接和硬鏈接,兩種鏈接適用于不同場合、不同用途,各有優缺點。在介紹軟硬兩種鏈接之前,需要先引入inode的概念。

Inode

    系統在管理文件時,為了有序尋址,會將元數據(metadata)和用戶數據(userdata)分開存放。元數據是指文件各類附加屬性,如ls –l命令中顯示的文件類型、權限、屬主屬組、文件大小、修改時間以及文件名等信息;而用戶數據是指真實的對用戶有用的數據。Linux不同路徑下可以創建相同文件名稱的文件,對于計算機系統來說,識別二進制數字比直接的文件名更為快捷。所以Linux系統用不同的數字來標識不同的文件,而此數字就是inode號,即索引節點號(index node)。元數據中的inode才是系統識別文件的唯一標識符。

blob.png

查看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

    硬鏈接數

    文件大小

    時間戳

    指針

    其他數據

blob.png

   簡而言之,對于Linux系統來說,所有的目錄映射都是文件之間的inode號映射。

   由于每個分區都有著自身的一套inode號,在執行類似于cp和mv的命令,會對目標文件的inode號有何影響?

cpinode

[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

rminode

  刪除文件其實就是釋放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號,刪除其中一個文件名,并不影響其他文件名的使用。多個硬鏈接名之間并無任何依賴關系存在。

blob.png

如果將文件跨分區進行硬鏈接,會出現設備結果?

[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文件刪除后,軟鏈接就呈現失效的狀態。

blob.png

那么在/Hisen/testdir1/下新建一個文件名為testfile2的文件會有什么效果呢?

blob.png

軟鏈接又恢復正常狀態,印證了軟鏈接并不關心文件里的具體內容。

另外,硬鏈接不能針對目錄,那么軟鏈接能否針對目錄呢?

blob.png

上圖已經證實,軟鏈接是可以針對于目錄做鏈接。

我們已經知道,硬鏈接是無法跨設備跨分區的,那么軟鏈接跨分區的效果如何?

blob.png

  正如所料到的那樣,一切正常,證明軟鏈接是可以跨設備跨分區的。

  接下來,關于鏈接路徑的寫法,軟鏈接和硬鏈接有著比較大的區別:

  ①當前目錄下:

  blob.png

  ②絕對路徑:

  blob.png

  ③相對于被鏈接文件路徑的相對路徑:

    blob.png

  綜上,軟鏈接支持絕對路徑和被鏈接文件路徑相對的路徑鏈接,但是由于在開發環境中考慮到可移植性,最好寫成相對路徑

總結

  通過上面兩節對軟鏈接和硬鏈接的介紹后,相信區別已經顯而易見了。不過還是需要好好的總結一下:

        1、命令格式:

硬鏈接:ln  filename  [linkname ]

軟鏈接ln  -s  filename  [linkname]

2、inode

硬鏈接:與被鏈接目標文件相同,創建時鏈接數遞增;

軟鏈接:與被鏈接目標文件不同,創建時目標文件inode引用計數不變。

3、依賴性:

硬鏈接:鏈接之后,與原名稱無關,直接指向真實的數據。刪除原文件名,不影響新文件名使用數據;

軟鏈接:鏈接之后,需要能在保存的路徑下匹配到相同的文件名。刪除原文件名,則鏈接失效。

4、存儲數據:

硬鏈接:直接指向真實的數據,相同的inode號;

軟鏈接:存儲的是被鏈接文件的路徑。

5、跨設備跨分區:

硬鏈接:不可以;

軟鏈接:可以。

6、鏈接路徑:

硬鏈接:可當前、可絕對、可相對被鏈接文件路徑;

軟鏈接:不可當前、可絕對,可相對被鏈接文件路徑。

7、鏈接對象:

硬鏈接:可文件、不可目錄;

軟鏈接:可文件、可目錄。


原創文章,作者:Hisen,如若轉載,請注明出處:http://www.www58058.com/53158

(0)
HisenHisen
上一篇 2016-10-20
下一篇 2016-10-20

相關推薦

欧美性久久久久