Linux中的硬链接和软链接
节选自南大蒋炎岩老师操作系统网络课程笔记:(2021) 24 [持久化] 文件系统API
硬(hard)链接
UNIX文件指针
在UNIX中,文件和目录完全不是同一个概念,虽然我们平时看着它们仿佛并列地躺在某个文件夹下。但实际上,目录是树状结构组织的,而文件,却是每个目录指向某个文件的指针。并且,每个文件都有一个编号,可能会有多个目录下的多个指针都指向同一个编号的文件。它们虽然存在于不同的目录下,甚至名称也不同,但是同一个编号的文件是完全相同的,修改也是同步的。如下图所示:
我们可以做这样的测试:
创建测试目录并在其中的a.txt
写入Hello World!
mkdir test && cd test && touch a.txt
vim a.txt # 写入 Hello World!
创建a.txt
的硬链接b.txt
:
ln a.txt b.txt
我们查看两个文件的内容,输出显示都是同样的Hello World:
cat *.txt
# 输出:
# Hello World!
# Hello World!
这时,我们修改b.txt
的内容为Hello World! Changed~
,再查看两个文件的内容:
vim b.txt # 更改为 Hello World! Changed~
cat *.txt
# 输出:
# Hello World! Changed~
# Hello World! Changed~
结果两个文件都被修改了,这就是硬链接,我们可以通过-i
参数查看文件的编号:
ls -i
# 输出:
# 8593746 a.txt 8593746 b.txt
可以看到,两个文件其实是同一个编号的文件的不同链接。即硬链接的图示如下:
硬链接
注意:
- 目录中仅存储指向文件数据的指针
- 允许一个文件被多个目录引用
- 不能链接目录 ❌
- 不能跨文件系统 ❌
小知识:其实所有的文件都是硬连接 (ls -i
查看)
- 删除的系统调用称为 “unlink” (引用计数)
应用场景
可以给文件起别名,同步,省空间。
需求:系统中可能有同一个运行库的多个版本
libc-2.27.so
,libc-2.26.so
, …- 还需要一个 “当前版本的 libc”
- 程序需要链接 “
libc.so.6
” - 能否避免文件的一份拷贝?
- 程序需要链接 “
软(symbolic)链接
软链接:在文件里存储一个 “跳转提示”,相当于”快捷方式“。
- 软链接也是一个文件
- 当引用这个文件时,去找另一个文件
- 另一个文件的绝对/相对路径以文本形式存储在文件里
- 可以跨文件系统、可以链接目录、……好处多多
- 甚至,符号链接可以指向一个暂时不存在的文件或目录,只要这个不存在文件或目录将来某天存在了,这个符号链接就会生效
ln -s
创建软链接,用的是symlink
系统调用。现在系统中/lib
下的共享库,通常都是软链接。
我们接着上面硬链接的例子来看一下二者的区别:
再在测试目录下创建a.txt
的软链接c.txt
:
ln -s a.txt c.txt
我们用-li参数查看测试目录中的三个文件:
ls -li
# 输出
# 8593746 -rw-rw-r-- 2 ps ps 22 10月 1 22:14 a.txt
# 8593746 -rw-rw-r-- 2 ps ps 22 10月 1 22:14 b.txt
# 8593742 lrwxrwxrwx 1 ps ps 5 10月 1 22:35 c.txt -> a.txt
在这里,b,c分别是a的硬、软链接。可以看到,a和c的文件编号是不一样的,因为它们是软链接,并且可以看到,c作为a的软链接,会有一个箭头指向a。但是,它们的修改仍然是同步的,因为我们在试图修改c的时候,系统会顺着上面输出的软链接箭头去寻找,直到找到一个真实的文件或者目录。我们还是来试一下:
vim c.txt # 修改为Hello World! Changed~ Soft~
cat *.txt
# 输出:
# Hello World! Changed~ Soft~
# Hello World! Changed~ Soft~
# Hello World! Changed~ Soft~
与预期一致。此时测试目录下的链接关系应该如下图所示:
软链接可能带来的麻烦
软链接可以随意创建 (当前可能不合法;但未来可能合法),操作系统在处理软链接时会执行路径解析,,允许多次间接链接,会有意想不到的复杂性 ,a → b → c (递归解析)。可以创建软连接的硬链接 (因为软链接也是文件),通过ls -i
可以看到。
符号链接成环?ln -s . a
。所有处理符号链接的程序 (tree, find, …) 都要考虑递归的情况。它们默认遇到软链接就跳过,如果加上-L参数强制使它们考虑软链接的话,它们也会很小心的检测成环和递归的情况并适时退出。