浅谈Linux软硬链接的联系和区别

1. 前言

前天因为在centOS7在命令行使用vim命令报错bash: vim: command not found on CentOS 7,Google后发现,可以root权限下,通过ln -s /usr/bin/vi /usr/bin/vim建立软链接解决这个问题。
因此就想了解一下软硬链接的区别,便看了几篇博客,有些博客讲的比较绕,看完一脸懵圈,有些写的很透彻,于是想把看到的好博客进行总结,一方面利于日后查看,另一方面也希望能帮助和我一样的小白,少走一些弯路。

2. Linux文件系统中的文件、inode、文件名和目录

为了更好地理解软硬链接,需要先简单的了解Linux中文件、inode、文件名和目录的概念。
现代操作系统为解决信息能独立于进程之外被长期存储引入了文件,文件作为进程创建信息的逻辑单元可被多个进程并发使用。
文件Linux系统中,除进程之外的一切皆是文件。文件都有文件名与数据,这在 Linux 上被分成两个部分:用户数据 (user data) 与元数据 (metadata)。用户数据,即文件数据块 (data block),数据块是记录文件真实内容的地方;而元数据则是文件的附加属性,比如创建时间、修改时间、文件大小、属主、归属的用户组、读写权限、数据所在block号等。
inode:在Linux的文件系统中,保存在磁盘分区中的文件,不管是什么类型都会给它分配一个编号,这个编号被称为索引节点编号(inode index)或者inode。inode 是文件元数据的一部分,但其并不包含文件名。在 Linux ,元数据中的 inode 号是文件在一个文件系统中的唯一标识,不同文件系统inode号可以相同。系统或程序通过 inode 号寻找正确的文件数据块,而不是文件名。换句话说,操作系统只认inode号,不认文件名,文件名是方便人类而存在的。
文件名:文件名仅是为了方便人们的记忆和使用,相当于给inode号起了一个人类便于记忆和使用的名字。
目录:目录是特殊的文件,是记录了其他文件名的文件。引入目录的原因是为了便于Linux管理文件,目录有时也被称为文件夹。目录使文件可被分类管理,且目录的引入使 Linux 的文件系统形成一个层级结构的目录树。实际上,Linux 与其他类 UNIX 系统一样,并不区分文件与目录。使用命令 mkdir 创建目录时,若期望创建的目录的名称与现有的文件名(或目录名)重复,则会创建失败。
下图是Linux 系统的顶层目录结构

/ 根目录
├── bin 存放用户二进制文件
├── boot 存放内核引导配置文件
├── dev 存放设备文件
├── etc 存放系统配置文件
├── home 用户主目录
├── lib 动态共享库
├── lost+found 文件系统恢复时的恢复文件
├── media 可卸载存储介质挂载点
├── mnt 文件系统临时挂载点
├── opt 附加的应用程序包
├── proc 系统内存的映射目录,提供内核与进程信息
├── root root 用户主目录
├── sbin 存放系统二进制文件
├── srv 存放服务相关数据
├── sys sys 虚拟文件系统挂载点
├── tmp 存放临时文件
├── usr 存放用户应用程序
└── var 存放邮件、系统日志等变化文件

下图展示了程序通过文件名获取文件内容的过程。
在这里插入图片描述

3. 什么是硬链接和软链接?

硬链接(Hard Link):在Linux系统中,多个文件名指向同一索引节点(Inode)是正常且允许的。一般这种链接就称为硬链接。
软链接(又称符号链接,即 soft link 或 symbolic link):类似于windows系统中的快捷方式,与硬链接不同,软链接就是一个普通文件,只是数据块内容有点特殊,文件用户数据块中存放的内容是另一文件的路径名的指向,通过这个方式可以快速定位到软连接所指向的源文件实体。软链接可对文件或目录创建。

4. 建立软硬链接语法

ln命令格式:
ln [参数] [源文件或目录] [目标文件或目录]
主要参数:
-i 交互模式,文件存在则提示用户是否覆盖。
-s 软链接(符号链接)。
-d 允许超级用户制作目录的硬链接。
-b 删除,覆盖以前建立的链接
软链接(symbolic link) :ln -s 源文件 目标文件
硬链接(hard link) :ln 源文件 目标文件
源文件:即你要对谁建立链接

5. 软硬链接的区别和联系

为了便于说明,我这里在/tmp目录下新建了text.txt文件。
在这里插入图片描述
往test.txt文件中写入I love Java
在这里插入图片描述
分别创建软硬链接以及分别用cp命令复制为test_cp1.txt和cp -p命令复制为text_cp2.txt。注:cp -p命令还会复制文件的创建时间等属性。查看相关文件信息如下:
在这里插入图片描述
可以发现:

  1. 软链接的文件test_soft.txt大小只有8,它的数据部分仅包含它所要链接文件的路径名,所以相对较小,创建时间也和源文件test.txt创建时间不同。
  2. 硬链接的文件test.hard.txt文件大小、创建时间都和源文件相同。手误,本来想命名为test_hard.txt的。
  3. cp 命令复制的文件test_cp1.txt文件大小和源文件相同,但是创建时间不同。
  4. cp -p命令复制的文件test_cp2.txt文件大小和创建时间都和源文件相同。
    继续查看各文件的inode,使用ls -i命令。
    在这里插入图片描述
    可以看到,只有建立硬链接时,得到的inode和源文件相同,复制或者软链接都会得到新的inode。
    那么我们修改一下源文件,往test.txt里面追加I love Python.。看看其他的软硬链接文件和复制文件会有什么变化?
    在这里插入图片描述
    复制的两个文件都没有被更新,可以看到软硬链接文件的内容都被更新了,并且硬链接的文件时间和源文件进行了同步,但是软链接文件的文件时间没有同步更新。
    那么,我们想一下,如果我更改硬链接文件,那么源文件和软链接文件会不会变呢?
    往test.hard.txt文件中写入I love C.,然后查看各文件信息和inode。
    在这里插入图片描述
    可以看到改变硬链接文件的效果和改变源文件的效果是一样的。综上我们可以分析得出,硬链接和源文件共享一个inode,每建立一个硬链接,就在inode的硬链接数(i_nlink)上+1,同理每删除一个硬链接,就在inode的硬链接数(i_nlink)上-1,如果inode的i_nlink计数为0,操作系统就会回收inode指向的存储空间,此时如果有新数据要存储到磁盘上,被删除的文件的数据块及目录的链接才会被释放,空间被新数据暂用覆盖。注意:这里的源文件test.txt也不过是一个符号而已,inode才是Linux真正识别的
    从而我们可以推断出,如果我们删除源文件test.txt,那么软链接文件读不到源文件了,从而报错,因为软链接文件保存的是源文件的路径信息,但是硬链接文件还在,只是inode硬链接数(i_nlink)-1。
    在这里插入图片描述
    软硬链接的访问如下图:
    在这里插入图片描述

6. 软硬链接的作用及应用场景

为解决文件的共享使用,Linux 系统引入了两种链接:硬链接 (hard link) 与软链接(又称符号链接,即 soft link 或 symbolic link)。链接为 Linux 系统解决了文件的共享使用,还带来了隐藏文件路径、增加权限安全及节省存储等好处。

6.1 硬链接的作用

  1. 允许一个文件拥有多个有效路径名,对重要的文件建立硬链接,以防止“误删”源数据(很多硬件,如netapp存储中的快照功能就应用了这个原理,增加一个快照就多了一个硬链接)。
  2. 实现在一个文件系统内的文件共享,解决存储空间。

6.2 软链接的作用

软链接的存在是为了解决硬链接存在的两个缺点:1)不能对目录进行链接;2)不能跨文件系统进行了链接。

  1. 便于文件的管理。比如把一个复杂路径下的文件链接到一个简单路径下方便用户访问,类似于windows下的桌面快捷键方式。
  2. 节省空间解决空间不足问题。因为软链接可以跨文件系统,所以当某个文件文件系统空间已经用完了,但是现在必须在该文件系统下,创建一个新的目录并存储大量的文件时,那么可以把另一个剩余空间较多的文件系统中的目录链接到该文件系统中。

7. 小结

硬链接相当于给文件取别名,inode不变;软链接类似于windows下的快捷键,对文件的一个名字进行了映射,有自己的inode。

7.1 硬链接特性

  1. 文件有相同的 inode 及 data block;
  2. 只能对已存在的文件进行创建;
  3. 不能交叉文件系统进行硬链接的创建;
  4. 不能对目录进行创建,只可对文件创建;
  5. 删除一个硬链接文件并不影响其他有相同 inode 号的文件。
# ls -li 
total 0 
 
// 只能对已存在的文件创建硬连接
# link old.file hard.link 
link: cannot create link `hard.link' to `old.file': No such file or directory 
 
# echo "This is an original file" > old.file 
# cat old.file 
This is an original file 
# stat old.file 
 File: `old.file'
 Size: 25 Blocks: 8 IO Block: 4096 regular file 
Device: 807h/2055d Inode: 660650 Links: 2 
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) 
... 
// 文件有相同的 inode 号以及 data block 
# link old.file hard.link | ls -li 
total 8 
660650 -rw-r--r-- 2 root root 25 Sep 1 17:44 hard.link 
660650 -rw-r--r-- 2 root root 25 Sep 1 17:44 old.file 
 
// 不能交叉文件系统
# ln /dev/input/event5 /root/bfile.txt 
ln: failed to create hard link `/root/bfile.txt' => `/dev/input/event5': 
Invalid cross-device link 
 
// 不能对目录进行创建硬连接
# mkdir -p old.dir/test 
# ln old.dir/ hardlink.dir 
ln: `old.dir/': hard link not allowed for directory 
# ls -iF 
660650 hard.link 657948 old.dir/ 660650 old.file

7.2 软链接特性

  1. 软链接有自己的文件属性及权限等;
  2. 可对不存在的文件或目录创建软链接;
  3. 软链接可交叉文件系统;
  4. 软链接可对文件或目录创建;
  5. 创建软链接时,链接计数 i_nlink 不会增加;
  6. 删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即 dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。
# ls -li 
 total 0 
 
 // 可对不存在的文件创建软链接
 # ln -s old.file soft.link 
 # ls -liF 
 total 0 
 789467 lrwxrwxrwx 1 root root 8 Sep 1 18:00 soft.link -> old.file 
 
 // 由于被指向的文件不存在,此时的软链接 soft.link 就是死链接
 # cat soft.link 
 cat: soft.link: No such file or directory 
 
 // 创建被指向的文件 old.file,soft.link 恢复成正常的软链接
 # echo "This is an original file_A" >> old.file 
 # cat soft.link 
 This is an original file_A 
 
 // 对不存在的目录创建软链接
 # ln -s old.dir soft.link.dir 
 # mkdir -p old.dir/test 
 # tree . -F --inodes 
 . 
├── [ 789497] old.dir/ 
│ └── [ 789498] test/ 
├── [ 789495] old.file 
├── [ 789495] soft.link -> old.file 
└── [ 789497] soft.link.dir -> old.dir/

不论是硬链接或软链接都不会将原本的档案复制一份,只会占用非常少量的磁盘空间。
以上相关特性的实际代码来自参考文献3。

8. 参考文献

站在巨人的肩膀上能够帮助我们少走弯路。
1 适合初步了解软硬链接,以及它们和复制的区别;
2 相对专业的介绍了软硬链接在操作系统中的实现以及意义;
3 这位大神写的非常好,帮助我们更加深入地去理解软硬链接,尤其是里面的inode和Linux文件系统,非常全面和深入,可以按照这个顺序把三篇博客看完,基本就对软硬链接有个基本的掌握了。

  1. 软链接和硬链接到底有啥作用和区别
  2. Linux系统硬链接和软链接
  3. 理解 Linux 的硬链接与软链接
发布了128 篇原创文章 · 获赞 157 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/qq_27283619/article/details/103248514