[Linux]硬链接和软链接

本文非纯原创,是各文杂糅而来加部分自身实践,在此致谢各位作者!

正文

说到硬链接(Hard link)与软链接(Symbolic link),首先需要了解索引节点(Inode)。关于Inode请移步这里。

硬链接

由于linux下的文件是通过索引节点(Inode)来识别文件,硬链接可以认为是一个指针,指向文件索引节点的指针,系统并不为它重新分配inode。inode指向了物理硬盘的一个区块,事实上文件系统会维护一个引用计数,只要有文件指向这个区块,它就不会从硬盘上消失。每添加一个一个硬链接,文件的链接数就加1

用ln命令来建立硬链接。

#用法
usage: ln [-Ffhinsv] source_file [target_file]
       ln [-Ffhinsv] source_file ... target_dir
       link source_file target_file

#创建前
➜  ~ ls -lrth tmp
-rw-r--r--  1 hanzhu  staff     0B Oct  9 20:41 tmp

#创建硬链接
➜  ~ ln tmp tmphard

#创建后
➜  ~ ls -ilrth tmp*
38351334 -rw-r--r--  2 hanzhu  staff     0B Oct  9 20:41 tmphard
38351334 -rw-r--r--  2 hanzhu  staff     0B Oct  9 20:41 tmp

注意在创建链接前, tmp显示的链接数目为1,创建链接后

  1. tmp和tmphard的链接数目都变为2;
  2. tmp和tmphard在inode号是一样的;
  3. tmp和tmphard显示的文件大小也是一样。
    可见进行了ln命令的操作结果:tmp和tmphard是同一个文件的两个名字,它们具有同样的索引节点号和文件属性,建立文件tmp的硬链接,就是为tmp的文件索引节点在当前目录上建立一个新指针。

如下示例,你可以删除其中任何一个,比如rm tmp ,每次只会删除一个指针,链接数同时减一,只有将所有指向文件内容的指针,也即链接数减为0时,内核才会把文件内容从磁盘上删除。

#删除
➜  ~ rm tmp
➜  ~ ls -ilrth tmp*
38351334 -rw-r--r--  1 hanzhu  staff     0B Oct  9 20:41 tmphard

不足:
尽管硬链接节省空间,也是Linux系统整合文件系统的传统方式,但是存在以下不足之处:

  1. 不可以在不同文件系统的文件间建立链接
  2. 只有超级用户才可以为目录创建硬链接。

一些硬链接总结:

  • 硬链接文件是普通文件,可以用rm删除;
  • 具有相同inode节点号的多个文件互为硬链接文件;
  • 删除硬链接文件或者删除源文件任意之一,文件实体并未被删除;
  • 只有删除了源文件和所有对应的硬链接文件,文件实体才会被删除;
  • 硬链接文件是文件的另一个入口;
  • 可以通过给文件设置硬链接文件来防止重要文件被误删;
  • 创建硬链接命令 ln 源文件 硬链接文件;
  • 对于静态文件(没有进程正在调用),当硬链接数为0时文件就被删除。注意:如果有进程正在调用,则无法删除或者即使文件名被删除但空间不会释放。

软链接

软链接克服了硬链接的不足,没有任何文件系统的限制,任何用户可以创建指向目录的符号链接。因而现在更为广泛使用,它具有更大的灵活性,甚至可以跨越不同机器、不同网络对文件进行链接。软链接的inode所指向的内容实际上是保存了一个绝对路径,当用户访问这个文件时,系统会自动将其替换成其所指的文件路径。

如果给ln命令加上- s选项,则建立软链接。如果[链接名] 已经存在但不是目录,将不做链接。[链接名]可以是任何一个文件名(可包含路径),也可以是一个目录,并且允许它与“目标”不在同一个文件系统中。如果[链接名]是一个已经存在的目录,系统将在该目录下建立一个或多个与“目标”同名的文件,此新建的文件实际上是指向原“目标”的符号链接文件。

用ln -s命令来建立软链接。

#创建软链接
➜  ~ ln -s  tmp tmpsoft

#创建后
➜  ~ ls -ilrth tmp*
38351334 -rw-r--r--  2 hanzhu  staff     0B Oct  9 20:41 tmphard
38351334 -rw-r--r--  2 hanzhu  staff     0B Oct  9 20:41 tmp
38364003 lrwxr-xr-x  1 hanzhu  staff     3B Oct  9 21:58 tmpsoft -> tmp

软链接与硬链接,区别不仅仅是在概念上,在实现上也是不同的。区别:

  1. 硬链接原文件&链接文件公用一个inode号,说明他们是同一个文件,而软链接原文件&链接文件拥有不同的inode号,表明他们是两个不同的文件;
  2. 在文件属性上软链接明确写出了是链接文件,而硬链接没有写出来,因为在本质上硬链接文件和原文件是完全平等关系;链接数目是不一样的,软链接的链接数目不会增加;
  3. 文件大小是不一样的,硬链接文件显示的大小是跟原文件是一样的,因为是等同的,而这里软链接显示的大小与原文件就不同了,tmp大小是0B,而tmpsoft是3B.

总之,建立软链接就是建立了一个新文件。当访问链接文件时,系统就会发现他是个链接文件,它读取链接文件找到真正要访问的文件。

缺点:

  1. 因为链接文件包含有原文件的路径信息,所以当原文件从一个目录下移到其他目录中,再访问链接文件,系统就找不到了,而硬链接就没有这个缺陷,你想怎么移就怎么移;
  2. 它要系统分配额外的空间用于建立新的索引节点和保存原文件的路径。

一些软链接总结:

  • 软链接类似windows系统的快捷方式;
  • 软链接里面存放的是源文件的路径,指向源文件;
  • 删除源文件,软链接依然存在,但无法访问源文件内容;
  • 软链接失效时一般是白字红底闪烁;
  • 创建软链接命令 ln -s 源文件 软链接文件;
  • 软链接和源文件是不同的文件,文件类型也不同,inode号也不同;
  • 软链接的文件类型是“l”,可以用rm删除。

融会贯通后你会发现:

  1. 删除符号连接tmpsoft,对tmp,tmphard无影响;
  2. 删除硬连接tmphard,对tmp,tmpsoft也无影响;
  3. 删除原文件tmp,对硬连接tmphard没有影响,导致符号连接tmpsoft失效;
  4. 同时删除原文件tmp,硬连接tmphard,整个文件会真正的被删除。
  5. 我们再向这个软链接写点东西,则可以看到,刚才删除的tmp文件竟然又出现了!这就说明,当我们写入访问软链接时,系统自动将其路径替换为其所代表的绝对路径,并直接访问那个路径了。
#删除tmp
➜  ~ rm tmp
➜  ~ ls -ilrth tmp*
38351334 -rw-r--r--  1 hanzhu  staff     0B Oct  9 20:41 tmphard
38364003 lrwxr-xr-x  1 hanzhu  staff     3B Oct  9 21:58 tmpsoft -> tmp

#对硬链接无影响(本来就是空文档)
➜  ~ cat tmphard

#软链接失效
➜  ~ cat tmpsoft
cat: tmpsoft: No such file or directory

#我们再向这个软链接写点东西
➜  ~ echo >> tmpsoft
➜  ~ ls -ilrth tmp*
38351334 -rw-r--r--  1 hanzhu  staff     0B Oct  9 20:41 tmphard
38364003 lrwxr-xr-x  1 hanzhu  staff     3B Oct  9 21:58 tmpsoft -> tmp
38377261 -rw-r--r--  1 hanzhu  staff     1B Oct  9 23:07 tmp

硬链接和软链接的区别

原理上,硬链接和源文件的inode节点号相同,两者互为硬链接。软连接和源文件的inode节点号不同,进而指向的block也不同,软连接block中存放了源文件的路径名。

实际上,硬链接和源文件是同一份文件,而软连接是独立的文件,类似于快捷方式,存储着源文件的位置信息便于指向。

使用限制上,不能对目录创建硬链接,不能对不同文件系统创建硬链接,不能对不存在的文件创建硬链接;可以对目录创建软连接,可以跨文件系统创建软连接,可以对不存在的文件创建软连接。

References:
Linux硬链接和软连接的区别与总结
关于硬链接和软连接(符号链接)的区别
5分钟让你明白“软链接”和“硬链接”的区别