在 Linux 的文件系統中,磁盤塊分成了 3 個部分。一部分稱為數據區,用來存放文件內容。另一部分稱為 inode 表,用來存放文件屬性。第三部分稱為超級塊,用來存放文件系統本身的屬性。文件的內容和屬性分開存放,文件的屬性存儲在一個稱為 inode 的數據結構中,inode 存放在 inode 表里,每個 inode 有一個唯一的編號對應其在 inode 表中的位置。
Linux 中有兩種鏈接:硬鏈接(Hard Link)和軟鏈接(Soft Link),軟鏈接也稱為符號鏈接(Symbolic Link)。
硬鏈接硬鏈接其實已存在文件的另一個名字,鏈接與原來的文件并沒有什么區別,它們共享一個 inode,而 inode 包含了一個文件的所有屬性。當為一個文件創建硬鏈時,內核不會分配新的 inode。
huey@huey-K42JE:~/huey/linux/cmdline$ touch f1huey@huey-K42JE:~/huey/linux/cmdline$ ln f1 f1-hardhuey@huey-K42JE:~/huey/linux/cmdline$ ls -litotal 010272788 -rw-rw-r-- 2 ng ng 0 APR 20 15:28 f110272788 -rw-rw-r-- 2 ng ng 0 Apr 20 15:28 f1-hard
系統并沒有為 f1-hard 分配新的 inode,f1-hard 的 inode 與 f1 一致,這說明了它們是同一個文件的兩個名字。創建鏈接后,f1 和 f1-hard 的鏈接數也由 1 增加到 2。再看看使用 rm 命令的過程:
huey@huey-K42JE:~/huey/linux/cmdline$ ls -litotal 010272788 -rw-rw-r-- 2 ng ng 0 Apr 20 15:33 f110272788 -rw-rw-r-- 2 ng ng 0 Apr 20 15:33 f1-hardhuey@huey-K42JE:~/huey/linux/cmdline$ rm f1huey@huey-K42JE:~/huey/linux/cmdline$ ls -litotal 010272788 -rw-rw-r-- 1 ng ng 0 Apr 20 15:33 f1-hardhuey@huey-K42JE:~/huey/linux/cmdline$ rm f1-hardhuey@huey-K42JE:~/huey/linux/cmdline$ ls -litotal 0
當刪除文件的時候,系統只是將文件的鏈接數減一,直到文件的鏈接數為 0 時,系統才會將磁盤的文件內容刪除。
硬鏈接有兩個重要的限制:1) 硬鏈接不能引用自身文件系統之外的文件。即鏈接不能引用與該鏈接不在同一磁盤分區的文件。2) 硬鏈接不能引用目錄(有些 Linux 版本允許超級用戶使用 -d 選項創建引用目錄的鏈接)。
符號鏈接符號鏈接是為了克服硬鏈接的局限性而創建的。符號鏈接是通過創建一個特殊類型的文件來起作用的,該文件包含了指向引用文件或目錄的文本指針。從這點來看,符號鏈接與 Windows 的快捷方式很相似。符號鏈接指向的文件與符號鏈接自身幾乎沒有區別。例如,將一些內容寫進符號鏈接里,那么這些內容同樣也寫進了引用文件。而當刪除一個符號鏈接時,刪除的只是符號鏈接而沒有刪除引用文件。如果先于符號鏈接之前刪除引用文件,那么這個鏈接依然存在,但是不指向任何文件。此時,這個鏈接就稱為壞鏈接。ls 命令一般會用不同的顏色來顯示壞鏈接,比如紅色。
軟鏈接相比硬鏈接有個不足的地方是:由于軟鏈接包含引用文件的路徑信息,所以如果引用文件移動到其他目錄,鏈接則變成一個壞鏈接。
ln 命令格式ln [OPTION]... [-T] TARGET LINK_NAME (1st form)ln [OPTION]... TARGET (2nd form)ln [OPTION]... TARGET... DIRECTORY (3rd form)ln [OPTION]... -t DIRECTORY TARGET... (4th form)
ln 命令參數--backup[=CONTROL] 如果指定的鏈接名已經存在,為該同名文件創建備份文件
-b 類似 --backup 選項,但不接受參數。
-d, -F, --directory 允許超級用戶創建目錄的硬鏈接(注:由于系統限制很有可能會失敗,即使是超級用戶)
-f, --force 如果指定的鏈接名已經存在,則覆蓋該同名文件
-n, --no-dereference 如果指定的鏈接名是一個引用目錄的符號鏈接,則將其當作是普通文件
-i, --interactive 如果指定的鏈接名已經存在,提示是否覆蓋該同名文件
-s, --symbolic 創建符號鏈接而非硬鏈接
-S, --suffix=SUFFIX 使用 SUFFIX 作為備份文件的后綴
-v, --verbose 顯示鏈接過程的信息
--help display this help and exit 打印幫助信息
--version 打印版本信息
ln 實例a) 創建硬鏈接
ln testfile testfile-hard
b) 創建符號鏈接
ln -s testfile testfile-sym
c) 強制創建鏈接,如果指定的鏈接名已經存在,則覆蓋該同名文件
ln -f testfile testfile-hard
d) 為被覆蓋的文件創建備份
ln -bf testfile testfile-hard
e)為被覆蓋的文件創建備份,并以 ".~[num]~" 作為后綴
ln -f --backup=numbered testfile testfile-hard
f) 為被覆蓋的文件創建備份,并指定備份文件的后綴為 ".bak"
ln -bf -S '.bak' testfile testfile-hardln 的 -n 選項
使用 man ln 命令,-n 選項的釋義是 "treat destination that is a symlink to a directory as if it were a normal file",如何理解?
假設有 a、b 兩個目錄,還有一個指向 a 目錄的軟鏈接 c:
huey@huey-K42JE:~/huey/linux/cmdline$ mkdir a bhuey@huey-K42JE:~/huey/linux/cmdline$ ln -s a c
現在如果要使軟鏈接 c 改為指向 b 目錄而執行下面這條命令:
huey@huey-K42JE:~/huey/linux/cmdline$ ln -sf b c
這并不能達到預期的效果,而是會在 c 的引用目錄(即 a 目錄)里創建 b 目錄的軟鏈接。這種情況下, -n 選項會將軟鏈接c 當作一個普通文件而被覆蓋:
huey@huey-K42JE:~/huey/linux/cmdline$ ln -sfn b c
新聞熱點
疑難解答