【Linux】文件操作篇(二):实战理解硬链接与软链接
本专栏文章持续更新,新增内容使用蓝色表示。
文件链接允许我们创建指向同一文件的多个文件名称。Linux提供了两种主要的链接方式:硬链接 和 软链接(也称为符号链接)。本文将深入探讨这两种链接的区别、工作原理和实际应用。
实验准备
输入以下命令创建实验测试环境,可根据自己需求调整:
mkdir link_test
cd link_testecho "这是测试文件链接的原始文件内容,创建时间: $(date)" > original_file.txtmkdir original_dir
echo "dir,这是测试文件链接的目录中的文件内容" > original_dir/file_inside.txt
查看创建结果:
ls -lhi
参数说明:
-l:显示文件详细信息
-h:以人类可读的形式显示大小
-i:显示inode编号

更多详细内容可以阅读本篇:
【Linux】权限管理详解(二):文件权限 | Redhat_linux文件夹权限-CSDN博客
硬链接
创建硬链接
使用 ln 命令创建一个指向现有文件的硬链接。
ln [现有文件] [硬链接]ln original_file.txt hard_link_file.txt

观察结果:
1)源文件和硬链接文件的inode编号相同
2)链接数从1变为2
3)两个文件除了名称不同外,其余信息完全一致:
- 访问权限
- 用户和组所有权
- 时间戳
- 文件内容

注意
1)不能对目录创建硬链接。
![]()
2)硬链接不同跨文件系统。
硬链接必须在同一个文件系统内创建,因为 inode 编号是文件系统局部的。(本文思考部分:Linux是如何存储文件的?中解释了inode)
此处可以自行尝试,创建不同文件系统类型,可以参考以下内容:
【Linux】存储管理详解(一):文件系统、分区、格式化与挂载实践 | Redhat_linux系统所支持的文件系统类型命令-CSDN博客
【Linux】存储管理详解(二):分区、格式化与挂载实战 | Redhat_linux 格式化分区-CSDN博客
测试
尝试修改源文件内容
echo "test test test" >> original_file.txtcat original_file.txt
cat hard_link_file.txt

尝试修改硬链接文件
echo "hard_link test" >> hard_link_file.txtcat original_file.txt
cat hard_link_file.txt

总结
当硬链接的信息发生更改时,同一文件的所有硬链接都会显示新的信息。这是因为:
-
所有硬链接共享相同的 inode
-
本质上指向相同的数据块
-
增加硬链接会使引用计数加1
-
类似于 C++ 中的 shared_ptr 概念
应用场景:高效备份,与复制不同,硬链接不占用额外磁盘空间。
软链接
软链接可以理解为创建了一个"快捷方式"。
创建软链接
ln -s [原始文件] [链接文件]ln -s original_file.txt soft_link_file.txt

软链接和源文件的区别
1)inode不同:软链接有自己独立的inode
2)文件类型不同:
源文件:-(普通文件)
软链接:l(符号链接)
3)其他信息不同:权限、链接数、所有权等都不同
访问文件的结果相同。
cat original_file.txt
cat soft_link_file.txt

不管创建多少个软链接,原始的文件内容只存储了一份。
应用场景:需要链接目录、跨文件系统、创建快捷方式、路径重定向
与硬链接的区别
总结一句话就是硬链接不能做的,软链接可以。
对目录创建符号链接
ln -s original_file.txt soft_link_file.txtls -lhi original_dir soft_link_dir

cd soft_link_dir
ls

跨文件系统创建符号链接
此处可以自行尝试,创建不同文件系统类型,可以参考以下内容:
【Linux】存储管理详解(一):文件系统、分区、格式化与挂载实践 | Redhat_linux系统所支持的文件系统类型命令-CSDN博客
【Linux】存储管理详解(二):分区、格式化与挂载实战 | Redhat_linux 格式化分区-CSDN博客
测试
尝试修改源文件内容
echo "test1 test1 test1" >> original_file.txtcat original_file.txt
cat hard_link_file.txt
尝试修改软链接文件
echo "soft_link test" >> soft_link_file.txtcat original_file.txt
cat hard_link_file.txt

探索
做一些好玩的事情。
对硬链接创建硬链接
ln hard_link_file.txt hard_to_hard.txtls -lhi hard_link_file.txt hard_to_hard.txt original_file.txt

结果是所有硬链接的 inode 相同,它们都是原始文件的等价引用。
对符号链接创建符号链接
ln -s soft_link_file.txt soft_to_soft.txtls -lhi soft_to_soft.txt soft_link_file.txt original_file.txt

多层链接,系统可以正常解析,可以正常访问。
对硬链接创建符号链接
ln -s hard_to_hard.txt soft_to_hard.txtls -lhi hard_to_hard.txt soft_to_hard.txt

对符号链接创建硬链接

这会创建符号链接文件本身的硬链接,而不是指向原始文件。
有其它的想法也可以进行尝试。
删除测试
删除源文件后,对硬链接和软链接有什么影响?
rm original_file.txt

软链接文件还在,但是链接失效了不能访问,变为悬空链接了。
![]()
硬链接不受影响。

复原之后呢?
echo "new file" > original_file.txt
软链接又恢复了。
![]()
思考
1. Linux是如何存储文件的?
数据存放在实际的物理硬盘上SSD/HDD。访问数据时主要通过 inode 和 block 定位到数据位置。
Linux通过以下组件管理文件存储:
inode:
-
指向数据块的唯一标识符
-
存储除文件名外的所有文件属性
-
在同一文件系统中唯一
-
大小通常为128B或256B
block:
-
实际存储数据的硬盘块
-
固定大小(通常4KB)
类比:类似于快递柜系统,inode是柜子编号,block是实际的存储空间。关于 inode 和 block 的大小可以在格式化时指定。一般情况下,默认即可。
inode 相关参数:
- -I bytes:指定每个 inode 的大小(ext4)
- -i bytes-per-inode:指定每多少字节分配一个 inode
- -N number-of-inodes:直接设置 inode 总数
block 相关参数:
- -b block-size:设置文件系统 block 大小
- 常见大小:1024、2048、4096 字节
一个 block 的大小是固定的(一般默认 4KB),如果一个文件的大小超过4KB,需要存储到多个 block中。读取文件时以block为单位读取,每读一个 block,消耗一次 IO,所以大文件在读取时会比较慢。
2. 硬盘空间有余,但是数据写不进去,可能的原因是什么?
空间有余,说明 block 有,但是数据写不进去,说明分配不到 inode,inode 的数目不够了。
导致这个问题发生的原因是由很多小文件(小于一个 block 的大小)存在,消耗了一整个 block 和一个 inode,但是实际只使用了一小部分,剩余部分不能被其它文件所使用,所以导致上述情况发生。
补充:使用 df -i 可以查看 inode 的使用情况,df -b 查看 block 的使用情况。
df -i # 查看inode使用情况
df -h # 查看磁盘空间使用情况
3. 怎样彻底删除一个文件?
1)考虑有没有硬链接,如果有硬链接,要将所有的硬链接删除。
2)文件是否被其它应用程序使用?
使用 vim 编辑文件时,会有一个对应的 swap 隐藏文件存在,此时如果要删除文件,需要将源文件和 swap 隐藏文件都删除掉。
# 原窗口
vim original_file.txt# 新窗口
ls -liha

补充:删除不了文件时,如何查看该文件被哪些进程所使用?
可以使用 lsof 命令(list openfile)。
lsof [filename] # 列出使用该文件的进程
4. 如何查看文件类型?
ls -l 查看文件在文件系统中属于什么文件类型,使用 file 命令查看实际上的文件类型(根据文件内容)。
ls -l [filename] # 查看文件系统类型
file [filename] # 分析实际文件类型
补充:windows 中通过文件后缀名区别文件类型,但是 linux 中文件名后缀只是用来提高可读性。
5. 硬链接和软链接的创建对 inode 的影响。
在文中有体现,硬链接不会创建新的 inode ,但是软链接会。
| 特性 | 硬链接 | 软链接 |
|---|---|---|
| inode | 共享原始文件的inode | 拥有独立的inode |
| 跨文件系统 | 不支持 | 支持 |
| 目录链接 | 不支持 | 支持 |
| 存储内容 | 直接指向数据块 | 存储目标文件路径 |
| 原始文件删除 | 不影响链接 | 链接失效 |
| 磁盘空间 | 不额外占用 | 占用少量空间存储路径 |
清理实验环境
# 回到 link_test 的上一级目录
cd ..rm -rf link_test
如有问题或建议,欢迎在评论区中留言~


