Linux中硬链接和软连接的介绍
1 硬链接
硬链接,也即“hard link”,其本质为现有文件的另一个名字,因此硬链接和原文件是无法区分的。从技术上讲,它们共享相同的inode,而inode几乎包含文件的所有信息,包括指向数据块的直接/间接指针。
1.1 硬链接的创建
创建硬链接的命令为ln [option] /path1/TARGET /path2/LINK_FILE
.其中/path1/TARGET
为原文件的路径,/path2/LINK_FILE
为即将创建的链接文件的路径及文件名。
[root@Centos7T app]#ll -i all
67 -rw-r--r--. 1 root root 24 Jul 22 10:48 all
[root@Centos7T app]#ln all all-link
[root@Centos7T app]#ls
all all-link
1.2 硬链接的特性
- 文件有相同的 inode 及 data block
利用ll -i file_name
可以查看文件的节点(inode)编号以及连接数。原文件all在创建硬链接之前节点编号为67,链接数为1。在当前工作目录创建链接文件all-link后,链接文件all-link的节点编号也是67,而此时all和all-link的连接数都变成2。由此可见,创建硬链接后,节点编号不变,连接数+1 。
使用命令stat
查看两个文件的元数据也都完全相同。
[root@Centos7T app]#ll -i !*
ll -i all all-link
67 -rw-r--r--. 2 root root 24 Jul 22 10:48 all
67 -rw-r--r--. 2 root root 24 Jul 22 10:48 all-link
[root@Centos7T app]#stat *
File: ‘all’
Size: 24 Blocks: 8 IO Block: 4096 regular file
Device: 805h/2053d Inode: 67 Links: 2
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:etc_runtime_t:s0
Access: 2017-07-22 10:48:25.224846470 +0800
Modify: 2017-07-22 10:48:22.610846516 +0800
Change: 2017-07-22 14:44:06.139596139 +0800
Birth: -
File: ‘all-link’
Size: 24 Blocks: 8 IO Block: 4096 regular file
Device: 805h/2053d Inode: 67 Links: 2
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:etc_runtime_t:s0
Access: 2017-07-22 10:48:25.224846470 +0800
Modify: 2017-07-22 10:48:22.610846516 +0800
Change: 2017-07-22 14:44:06.139596139 +0800
Birth: -
- 只能对已存在的文件进行创建
如果链接文件的命名与已存在文件重复,则链接文件不会被创建,同时输出报错信息:
[root@Centos7T app]#ln aa aa-link
ln: failed to access ‘aa’: No such file or directory
[root@Centos7T app]#ln all all-link
ln: failed to create hard link ‘all-link’: File exists
- 删除一个硬链接文件并不影响其他有相同inode号的文件
既然硬链接和原文件本质是同一个,那么我删除其中一个文件,会对另一个文件有影响吗?
首先尝试删除新建的链接文件:
[root@Centos7T app]#cat all
Welcome to Linux World!
[root@Centos7T app]#ll -i *
67 -rw-r--r--. 2 root root 24 Jul 22 10:48 all
67 -rw-r--r--. 2 root root 24 Jul 22 10:48 all-link
[root@Centos7T app]#rm -f all-link
[root@Centos7T app]#cat all
Welcome to Linux World!
[root@Centos7T app]#ll -a *
67 -rw-r--r--. 1 root root 24 Jul 22 10:48 all
删除链接文件后,原文件的连接数再次回到1,其他元数据及数据块本身没有任何变化。
现在重新创建硬链接,并删除原文件:
[root@Centos7T app]#ln all all-link
[root@Centos7T app]#cat all-link
Welcome to Linux World!
[root@Centos7T app]#ll -i *
67 -rw-r--r--. 2 root root 24 Jul 22 10:48 all
67 -rw-r--r--. 2 root root 24 Jul 22 10:48 all-link
[root@Centos7T app]#rm -f all
[root@Centos7T app]#cat all-link
Welcome to Linux World!
[root@Centos7T app]#ll -i *
67 -rw-r--r--. 1 root root 24 Jul 22 10:48 all-link
由此可见,硬链接和原文件的删除操作相互之间没有影响(连接数会减少)。
- 不能交叉文件系统(分区)进行硬链接的创建
在我的实验系统中,”/tmp”和”/app”分别在两个独立的分区
[root@Centos7T app]#df -h /tmp /app
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 50G 3.7G 47G 8% /
/dev/sda5 50G 33M 50G 1% /app
现在对/app
下的文件all尝试创建两个硬链接,一个位于/app,一个位于/tmp
[root@Centos7T app]#ll -i *
67 -rw-r--r--. 1 root root 0 Jul 22 16:47 all
[root@Centos7T app]#ln all all-link
[root@Centos7T app]#ll -i *
67 -rw-r--r--. 2 root root 0 Jul 22 16:47 all
67 -rw-r--r--. 2 root root 0 Jul 22 16:47 all-link
[root@Centos7T app]#ln all /tmp/all-link
ln: failed to create hard link ‘/tmp/all-link’ => ‘all’: Invalid cross-device link
结果显示位于/app下的硬链接创建成功,而位于/tmp下的硬链接无法创建并报错“Invalid cross-device link”
- 不能对目录进行创建,只可对文件创建
[root@Centos7T app]#mkdir test
[root@Centos7T app]#ll -id test/
33555264 drwxr-xr-x. 2 root root 6 Jul 22 17:08 test/
[root@Centos7T app]#ln -d test/ test-link/
ln: target ‘test-link/’ is not a directory: No such file or directory
[root@Centos7T app]#mkdir test-link/
[root@Centos7T app]#ln test/ test-link/
ln: ‘test/’: hard link not allowed for directory
在实验中,我们对已有目录test在当前目录创建硬链接test-link,直接报错链接目录不存在(target ‘test-link/’ is not a directory: No such file or directory)。于是新建目录test-link,重新创建硬链接,还是报错不允许给目录创建硬链接(hard link not allowed for directory)。
至此,有关硬链接的5条特性均用代码完成验证。
2 软链接
软链接,也称为符号链接,即“symbolic links/soft links”,是一个通过名称指向另一个不同文件的特殊的文件类型,是一个单独的文件,有着不同于原文件(目标文件)的属性,相当于Windows系统中的快捷方式。当对软链接进行大多数操作(包括打开、读取、写入等等)时,系统内核会自动在软链接的目标文件上执行;但某些操作,例如删除,会直接对链接文件本身操作。
2.1 软链接的创建
创建软链接的命令为ln -s /path1/TARGET /path2/LINK_FILE
.其中/path1/TARGET
为目标文件的路径,/path2/LINK_FILE
为即将创建的链接文件的路径。
[root@Centos7T app]#ll -i *
70 -rw-r--r--. 1 root root 24 Jul 22 19:51 soft
[root@Centos7T app]#ln -s soft soft-link
2.2 软链接的特性
- 软链接和目标文件不是同一个文件,节点号不同
获取目标文件和链接文件相关属性信息
[root@Centos7T app]#ll -i *
70 -rw-r--r--. 1 root root 24 Jul 22 19:51 soft
67 lrwxrwxrwx. 1 root root 4 Jul 22 19:51 soft-link -> soft
注意观察软连接文件soft-link的各项属性与目标文件soft的区别,软链接文件类型为链接文件,目标文件类型为普通文件,另外,软链接的节点编号、权限、大小等属性与目标文件均不相同。同时,创建软链接后,目标文件的连接数并对应不增加。显然,软链接文件和目标文件是两个不同的文件。但是,对软链接文件的读取、写入等操作都自动转到对目标文件的操作(注意删除操作除外)。
[root@Centos7T app]#cat soft-link
Welcome to Linux World!
[root@Centos7T app]#echo 'Hello World!' >> soft-link
[root@Centos7T app]#cat soft
Welcome to Linux World!
Hello World!
- 可对目录创建软链接
前面提到不可对目录创建硬链接,但是可以对目录创建软链接。
[root@Centos7T app]#ll -id test
69 drwxr-xr-x. 2 root root 6 Jul 22 20:57 test
[root@Centos7T app]#ln -s test test-link
[root@Centos7T app]#ll -id te*
69 drwxr-xr-x. 2 root root 6 Jul 22 20:57 test
70 lrwxrwxrwx. 1 root root 4 Jul 22 20:57 test-link -> test
软链接的创建还有个很重要的特性,它可以对不存在的文件、目录进行创建。当然,由于目标文件/目录不存在,此刻我们还不能通过软链接访问目标,这样的软链接称为“死链”。 死链在终端中会闪烁显示出来。
[root@Centos7T app]#ln -s unknown unknown-link
[root@Centos7T app]#ll -i un*
71 lrwxrwxrwx. 1 root root 7 Jul 22 21:00 unknown-link -> unknown
当然,如果我们在当前目录创建一个名为unknown的文件夹,那么软链接unknown-link会立即指向unknown文件夹,我们也可通过访问unknown-link来访问unknown。如果我们创建的是一个名为unknown的文件,并写入内容。那么unknown-link也会立即指向该文件,我们可以通过对unknown-link的读取、写入等操作实际操作unknown文件。即,可以针对不存在的文件或目录创建软链接。
[root@Centos7T app]#ln -s unknown unknown-link
[root@Centos7T app]#ll -i un*
71 lrwxrwxrwx. 1 root root 7 Jul 22 21:00 unknown-link -> unknown
[root@Centos7T app]#mkdir unknown
[root@Centos7T app]#ll -id un*
33555328 drwxr-xr-x. 2 root root 6 Jul 22 21:13 unknown
71 lrwxrwxrwx. 1 root root 7 Jul 22 21:00 unknown-link -> unknown
删除unknown文件夹,重新创建unknown文件,并写入内容
[root@Centos7T app]#rm -rf unknown
[root@Centos7T app]#ll -i un*
71 lrwxrwxrwx. 1 root root 7 Jul 22 21:00 unknown-link -> unknown
[root@Centos7T app]#echo 'Welcome to Linux World!' > unknown
[root@Centos7T app]#ll -i un*
72 -rw-r--r--. 1 root root 24 Jul 22 21:15 unknown
71 lrwxrwxrwx. 1 root root 7 Jul 22 21:00 unknown-link -> unknown
[root@Centos7T app]#cat unknown-link
Welcome to Linux World!
- 目标文件的删除操作会影响软链接文件
删除软链接
[root@Centos7T app]#ll -id *
68 -rw-r--r--. 1 root root 37 Jul 22 20:42 soft
67 lrwxrwxrwx. 1 root root 4 Jul 22 20:34 soft-link -> soft
69 drwxr-xr-x. 2 root root 6 Jul 22 20:57 test
70 lrwxrwxrwx. 1 root root 4 Jul 22 20:57 test-link -> test
[root@Centos7T app]#
[root@Centos7T app]#rm -rf soft-link test-link
[root@Centos7T app]#ll -id *
68 -rw-r--r--. 1 root root 37 Jul 22 20:42 soft
69 drwxr-xr-x. 2 root root 6 Jul 22 20:57 test
删除目标文件
[root@Centos7T app]#ll -id *
68 -rw-r--r--. 1 root root 37 Jul 22 20:42 soft
67 lrwxrwxrwx. 1 root root 4 Jul 22 21:26 soft-link -> soft
69 drwxr-xr-x. 2 root root 6 Jul 22 20:57 test
70 lrwxrwxrwx. 1 root root 4 Jul 22 21:27 test-link -> test
[root@Centos7T app]#rm -rf soft test
[root@Centos7T app]#ll -id *
67 lrwxrwxrwx. 1 root root 4 Jul 22 21:26 soft-link -> soft
70 lrwxrwxrwx. 1 root root 4 Jul 22 21:27 test-link -> test
[root@Centos7T app]#cat soft-link
cat: soft-link: No such file or directory
[root@Centos7T app]#cd test-link
-bash: cd: test-link: No such file or directory
上述两段代码可以看出,当链接文件被删除时,不会对目标文件产生影响;当删除目标文件/目录时,由于失去了目标指向,软链接会失效,变成死链。
- 能交叉文件系统(分区)进行软链接的创建
给/app/soft
分别在两个分区/app
和/tmp
路径下创建两个软链接
[root@Centos7T app]#df -h /app /tmp
Filesystem Size Used Avail Use% Mounted on
/dev/sda5 50G 33M 50G 1% /app
/dev/sda2 50G 3.7G 47G 8% /
[root@Centos7T app]#ln -s /app/soft /app/soft-link
[root@Centos7T app]#ln -s /app/soft /tmp/soft-link
[root@Centos7T app]#ll -i /app/soft-link /tmp/soft-link
67 lrwxrwxrwx. 1 root root 9 Jul 22 21:45 /app/soft-link -> /app/soft
69008408 lrwxrwxrwx. 1 root root 9 Jul 22 21:45 /tmp/soft-link -> /app/soft
[root@Centos7T app]#cat /app/soft-link /tmp/soft-link
Welcome to Linux World!
Welcome to Linux World!
跨分区的软链接创建成功。
- 软链接中目标文件相对路径的使用
在上面创建/tmp/soft-link
时我犯了个错误,导致软链接创建成功,但是提示是死链,无法指向/app/soft
。这个错误我再此复现:
[root@Centos7T app]#ln -s soft /tmp/soft-link
[root@Centos7T app]#ll -i /tmp/soft-link
69008408 lrwxrwxrwx. 1 root root 4 Jul 22 21:54 /tmp/soft-link -> soft
[root@Centos7T app]#cat /tmp/soft-link
cat: /tmp/soft-link: No such file or directory
这个错误实际上是由创建软链接时错误的使用目标文件的相对路径导致的。观察/tmp/soft-link -> soft
,可以发现,软链接/tmp/soft-link
实际指向的不是/app/soft
,而是/tmp/soft
,而在/tmp
中不存在soft文件,故成为死链。实际上,即便恰好存在,软链接不是死链,但还是与我们的操作原意不符。
创建软链接时,目标文件的相对路径应该是相对于链接文件的相对位置,而非相对于当前工作目录的相对位置
[root@Centos7T app]#ll -i soft
68 -rw-r--r--. 1 root root 24 Jul 22 21:39 soft
[root@Centos7T app]#ln -s soft /home/geoffrey/Desktop/soft-link1
[root@Centos7T app]#ln -s ../../../app/soft /home/geoffrey/Desktop/soft-link2
[root@Centos7T app]#cd /home/geoffrey/Desktop/
[root@Centos7T Desktop]#ll -i so*
1575524 lrwxrwxrwx. 1 root root 4 Jul 22 22:37 soft-link1 -> soft
1575200 lrwxrwxrwx. 1 root root 17 Jul 22 22:37 soft-link2 -> ../../../app/soft
[root@Centos7T Desktop]#cat soft-link1
cat: soft-link1: No such file or directory
[root@Centos7T Desktop]#cat soft-link2
Welcome to Linux World!
软链接soft-link1实际上是死链,其指向的soft在Desktop
找不到;soft-link2正常,其指向的../../../app/soft
最终指向了/app/soft
。当然,目标文件使用绝对路径,就不会有这样的错误了。