深色模式
硬链接与软链接
结论先行
在 Linux 和 macOS 这类 Unix 系统中,硬链接与软链接最核心的区别只有一句话:
- 硬链接链接的是
inode - 软链接链接的是路径
由此会带来几种常见差异:
- 删除源文件后,硬链接通常还能访问,软链接通常会失效
- 硬链接通常不能跨文件系统,软链接可以
- 硬链接通常不能指向目录,软链接可以
如果只想先记住怎么用,可以先记这一句:
- 更关注“是不是同一份真实数据”,想到硬链接
- 更关注“一个路径跳到另一个路径”,想到软链接
概述
很多人在第一次接触链接时,只记住了“硬链接像副本,软链接像快捷方式”这句话。但真正使用时,往往还是会遇到几个问题:
- 删除原文件后,为什么有的链接还能用,有的不能用。
- 为什么硬链接通常不能跨分区。
- 为什么软链接可以指向目录,而硬链接通常不行。
理解这些问题的关键,在于分清链接到底是指向 inode,还是指向路径。
先理解文件名与 inode
要理解硬链接,先要区分两个东西:
- 文件名
- 文件内容和元数据
在类 Unix 文件系统中,目录里保存的通常不是文件内容本身,而是“文件名到 inode 的映射”。inode 可以理解成文件的身份证,它记录了文件的元数据,以及文件内容所在的位置。
也就是说,平时看到的 a.txt,本质上更像是“一个名字指向某个 inode”。
理解了这一点,就容易看出两种链接的差别:
- 硬链接:给同一个 inode 再起一个名字。
- 软链接:创建一个新的特殊文件,里面保存另一个路径。
用图来表示会更直观。
硬链接更像是两个文件名同时指向同一个 inode:
软链接则是先指向一条目标路径,再由这条路径找到真正文件:
什么是硬链接
硬链接的本质,是多个文件名同时指向同一个 inode。
例如:
sh
echo "hello" > a.txt
ln a.txt b.txt执行完成后,a.txt 和 b.txt 指向的是同一个 inode。这不是复制出一个新文件,而是给同一个文件增加了另一个入口。
这会带来几个直接结果:
- 修改
a.txt,读取b.txt时也会看到修改后的内容。 - 修改
b.txt,读取a.txt时结果也一样。 - 删除
a.txt后,只要b.txt还在,文件内容就还在。 - 只有当最后一个硬链接被删除后,文件数据才会真正失去引用,随后被回收。
可以用 ls -li 查看 inode 和链接数:
sh
ls -li a.txt b.txt你通常会看到两行的 inode 编号相同,并且链接数大于 1。
什么是软链接
软链接也叫符号链接,通常可以理解为“路径级别的引用”。
例如:
sh
echo "hello" > a.txt
ln -s a.txt b.txt这时的 b.txt 并不是和 a.txt 共用同一个 inode 的普通文件,而是一个单独的链接文件。这个文件里记录的是目标路径 a.txt。
因此,软链接的行为和硬链接很不一样:
b.txt依赖它记录的目标路径。- 如果
a.txt被删除,b.txt就会失效。 - 这个失效的软链接通常被称为“悬空链接”或“坏链接”。
- 访问软链接时,系统会先根据它记录的路径找到真正目标,再去访问目标文件。
查看软链接时,ls -l 往往能直接看出来:
sh
ls -l b.txt可能会看到类似结果:
sh
b.txt -> a.txt这说明 b.txt 自己只是一个“指向 a.txt 的说明”。
硬链接与软链接的区别
最核心的区别可以再次概括为:
- 硬链接链接的是
inode。 - 软链接链接的是路径。
围绕这句话,会展开很多行为差异。
删除源文件时
硬链接场景下,删除原始名字不影响另一个名字继续访问文件,因为它们本来就是同一个 inode 的不同入口。
软链接场景下,如果被指向的目标被删掉,软链接就失效了。
是否可以跨文件系统
硬链接通常不能跨文件系统或分区,因为 inode 编号只在当前文件系统内部有意义。
软链接可以跨文件系统,因为它只保存路径字符串。
是否可以链接目录
硬链接通常不允许普通用户对目录创建,以避免目录结构形成环,影响文件系统遍历和管理。
软链接可以指向目录,所以很多场景下目录跳转、版本切换、路径兼容都会使用软链接。
inode 是否相同
硬链接和目标文件的 inode 相同。
软链接有自己独立的 inode,因为它自己本身也是一个文件,只不过内容是目标路径。
占用空间
硬链接不会额外复制文件内容,因此不会再占用一份完整的文件数据空间。
软链接通常只占很少的空间,因为它只需要保存目标路径等少量信息。
什么时候用硬链接
硬链接更适合“希望多个名字都代表同一份真实数据”的场景。
常见场景有:
- 需要同一文件的多个入口,但不希望复制数据。
- 需要保证即使某个路径被删除,文件仍能通过其他名字访问。
- 某些备份工具会利用硬链接减少重复文件占用。
但它也有限制:
- 一般不能跨分区。
- 一般不能给目录创建硬链接。
- 不容易从直觉上看出谁是“原文件”,因为从文件系统角度看,它们地位相同。
什么时候用软链接
软链接更适合“希望一个路径指向另一个路径”的场景。
常见场景有:
- 给很长的真实路径创建一个更短、更稳定的访问入口。
- 给目录做别名。
- 做版本切换,例如
current指向某个发布目录。 - 兼容旧路径,例如程序仍访问旧目录,但旧目录实际上链接到了新位置。
它的优点是灵活,限制少,但也要注意:
- 目标一旦移动或删除,软链接可能失效。
- 如果使用相对路径创建软链接,移动位置后更容易出错。
常用命令
创建硬链接
sh
ln 原文件路径 硬链接路径例如:
sh
ln a.txt b.txt创建软链接
sh
ln -s 目标路径 软链接路径例如:
sh
ln -s a.txt b.txt查看 inode
sh
ls -li查看软链接指向
sh
ls -l一个简单例子
下面用一个最小示例把两者的差异串起来。
先创建普通文件:
sh
echo "v1" > demo.txt创建硬链接和软链接:
sh
ln demo.txt demo-hard.txt
ln -s demo.txt demo-soft.txt此时:
demo.txt和demo-hard.txt指向同一个 inode。demo-soft.txt只是记录了demo.txt这个路径。
如果执行:
sh
rm demo.txt那么结果通常是:
demo-hard.txt仍然可以正常读取内容。demo-soft.txt会失效,因为它记录的路径不存在了。
这就是两者最典型的差异:硬链接保留的是对同一份数据的引用,软链接保留的是一条路径。
常见误区
硬链接不是文件副本
硬链接不会复制出一份新的文件内容。它只是让同一份数据多了一个目录项。
软链接不等于 Windows 快捷方式
把软链接类比为快捷方式有助于入门,但它比普通快捷方式更“底层”,很多程序会直接把它当路径解析过程的一部分,而不是单纯的桌面入口。
硬链接没有“主次之分”
很多人会问“谁才是原文件”。对硬链接来说,这个问题通常没有意义。只要多个名字指向同一个 inode,它们在文件系统层面就是平等的。
如果只想快速判断该用哪一种链接,可以用下面两条做区分:
- 希望多个名字对应同一份真实数据,用硬链接。
- 希望一个路径跳转到另一个路径,用软链接。
再补一句最关键的判断依据:
- 硬链接依赖
inode。 - 软链接依赖路径。
理解了这一点,删除文件、跨分区、目录链接这些行为差异就都比较容易解释了。
