懶人版"一天"一個Linux命令之ln

Linux 中的文件分爲 Hard Link 和 Symbolic Link 兩種。Hard Link 文件又被稱爲硬鏈接文件、實體鏈接文件,Symbolic Link 文件則常被稱爲符號鏈接、軟鏈接文件。

ln 命令用來在文件之間建立鏈接。在介紹 ln 命令前,讓我們先來搞清楚究竟什麼是硬鏈接,什麼又是軟鏈接。

Hard Link(硬鏈接)

我們知道,在 Linux 系統中,每個文件對應一個 inode,文件的內容在存儲在 inode 指向的 data block 中。要讀取該文件的內容,需要通過文件所在的目錄中記錄的文件名找到文件的 inode 號,然後通過 inode 找到存儲文件內容的 data block。

也就是說,文件名存儲在目錄中,inode 號執行文件存儲的內容,文件名和 inode 之間有一個對應關係。那麼多個文件名可不可以同時指向同一個 inode 呢?答案是可以的,這就是硬鏈接!從本質上來說,硬鏈接只是在目錄下新添加了一個文件名,這個文件名與一個已有文件的 inode 相關聯。讓我們也通過 /etc/crontab 文件來進行觀察:

$ ll -i /etc/crontab131213 -rw-r--r-- 1 root root 722 Nov 16  2017 /etc/crontab

使用 ln 命令在當前目錄下創建一個 /etc/crontab 文件的硬鏈接,然後觀察其文件屬性:

$ sudo ln /etc/crontab .$ ll -i /etc/crontab crontab131213 -rw-r--r-- 2 root root 722 Nov 16  2017 crontab131213 -rw-r--r-- 2 root root 722 Nov 16  2017 /etc/crontab

這兩個文件名關聯的 inode 號完全相同,都是 131213,所以它們指向的是同一個文件。同時請注意文件屬性中的第三個字段,由 1 變成了 2。這個字段被稱爲 "鏈接數",它說明有多少個文件名鏈接到同一個文件的 inode。

另外需要注意的一點是上面所有輸出中的第二個字段中的第一位,它們都是 "-",它說明這個文件的類型爲普通文件,鏈接類型爲硬鏈接。

我們可以通過下圖來理解硬鏈接在文件系統中的實現方式:

硬鏈接的特點

  • 幾乎不額外佔用空間

  • 只要還有一個文件名引用着文件,文件就不會被真正刪除

由於硬鏈接只是在目錄中添加了一條包含文件名和 對應 inode 的記錄,所以它幾乎不會消耗額外的磁盤容量。

另外在刪除硬鏈接所關聯的文件時,其實只是刪除了一條目錄中的記錄,真正的文件並不受影響。只有在刪除最後一個硬鏈接時纔會真正刪除文件的內容數據。

硬鏈接的侷限性

  • 不能跨文件系統創建硬鏈接

  • 不能鏈接目錄

由於這兩個限制,實際使用中硬鏈接並沒有軟鏈接使用的廣泛,下面我們看看究竟什麼是軟鏈接。

Symbolic Link(軟鏈接)

軟鏈接的實現方式與硬鏈接有本質上的不同。創建軟鏈接時會創建一個新的文件(分配一個 inode 和對應的 data block),新文件的 data block 中存儲了目標文件的路徑。
還拿 /etc/crontab 文件舉例子,這次創建一個軟鏈接並查看其文件屬性:

$ sudo ln -s /etc/crontab crontab2

第一列,兩個文件名對應的 inode 不同,說明這是兩個文件。

第二列顯示的文件權限也不一樣,這一點和硬鏈接完全不同。注意文件類型被標記爲 "l",說明這是一個軟鏈接文件。

第三列很有意思,注意 /etc/crontab 文件的鏈接數量,還是 2,這和創建軟鏈接文件 crontab2 前是一樣的。也就是說創建軟鏈接並不增加原文件的鏈接數。

第六列是文件大大小,注意新建的軟鏈接文件大小爲 12 Bytes,也就是字符串 "/etc/crontab" 的長度。

最後一列會友好的顯示出軟鏈接文件指向的源文件。

我們可以通過下圖來理解軟鏈接在文件系統中的實現方式:

從上圖我們可以看出,軟鏈接文件 crontab2 是一個實實在在的文件,有自己的 inode 和 data block。但是它的 data block 中保存的是目標文件的地址:/etc/crontab。 像 open() 這樣的 API 能夠識別出軟鏈接,並根據 data block 中的目標文件徑把操作重定向到目標文件上。

可以鏈接目錄是軟鏈接的一大優勢,創建目錄鏈接的方式和普通文件一樣:

$ ln -s /bin testbin

此時進入 testbin 目錄和進入 /bin 目錄是一樣的。

更厲害的是,還可以跨文件系統創建軟鏈接!

刪除源文件

對於軟鏈接來說,刪除源鏈接後,鏈接文件就會無法找到指向的源文件了。看下面的演示:

$ echo "hello world" > hello.txt$ ln -s hello.txt hello2$ cat hello2hello world$ rm hello.txt$ cat hello2cat: hello2: No such file or directory

刪除原文件後,操作鏈接文件時的提示是:"No such file or directory"。

文件的鏈接數

從上文中的示例我們可以看到,當創建硬鏈接文件時,文件的鏈接數會增加 1,而創建軟鏈接時文件的鏈接數卻不發生變化。

下面讓我們看一個目錄文件的鏈接數,先創建一個空目錄:

$ mkdir /home/nick/testdir$ ll  /home/nick | grep testdirdrwxr-xr-x  2 nick nick  4096 Jul 10 08:58 testdir/

新建的空目錄有兩個硬鏈接,分別是:

/home/nick/testdir/home/nick/testdir/.

而 /home/nick/testdir 目錄下還有一個指向其父目錄的硬鏈接:/home/nick/testdir/..

也就是說當我們創建一個目錄時,其父目錄的硬鏈接數會增加 1。

ln 命令

ln 命令用來在文件之間建立鏈接,其的常用方式爲:

ln source target
ln -s source target

它們分別用來創建硬鏈接文件和軟鏈接文件。還有一個比較常用的選項是 f,它會強制刪除已經存在的目標文件。

文章轉載於良許Linux微信公衆號,有興趣的小夥伴可以關注一下!
https://mp.weixin.qq.com/s/qSb0OqJX3UEGt4nLRNwgDw

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章