ls -li第一列就是 inode 号,inode 号相同说明是同一个文件本体。
约 1500 字大约 5 分钟
2026-05-14
“我明明把日志文件删了,磁盘空间怎么没释放?”“两个文件名指的是同一个东西吗?”这类问题的答案,都藏在 inode 这个概念里。理解了 inode,文件名、硬链接、软链接的关系就一目了然。
从 inode 的角度理解文件名只是“指向”,弄清硬链接和软链接的本质区别,解释“删了文件空间没释放”这类现象。
ls -li第一列就是 inode 号,inode 号相同说明是同一个文件本体。
stat fileLinks 字段是有多少个文件名指向这个 inode。
ln a bb 和 a 共享同一个 inode,地位完全平等。
ln -s a bb 是独立文件,内容是字符串 a,目标没了就悬空。
在 Linux 文件系统里,一个文件其实是两部分:
也就是说,文件名不是文件本身,只是指向 inode 的一个标签。ls -li 第一列就是 inode 号:
ls -li
# 1313742 -rw-r--r-- 2 me me 20 May 14 10:00 report.txt
# 1313742 -rw-r--r-- 2 me me 20 May 14 10:00 report-backup.txt上面两个文件名 inode 号相同(1313742),它们指向的是同一个文件本体。
ln a b 创建硬链接,效果是 b 和 a 指向同一个 inode。它们地位完全平等,没有“谁是源、谁是链接”之分。inode 里有个“链接计数”,记录有多少个文件名指向它:
ln report.txt report-backup.txt
stat report.txt # Links: 2
rm report.txt # 只是删掉一个名字,Links 变 1,数据还在
rm report-backup.txt # 最后一个名字也没了,Links 归 0,数据才真正释放这解释了“删文件”的真相:rm 删的是目录项(一个名字),只有当 inode 的链接计数归零,数据块才被回收。硬链接的限制:不能跨文件系统(inode 号只在本文件系统内唯一),通常也不能链接目录。
ln -s a b 创建软链接(符号链接)。b 是一个独立的新文件,有自己的 inode,内容就是字符串 "a"。访问 b 时,系统读出这个路径再转去访问。
| 对比项 | 硬链接 | 软链接 |
|---|---|---|
| 本质 | 同一个 inode 的另一个名字 | 独立文件,内容是目标路径 |
| 跨文件系统 | 不行 | 可以 |
| 链接目录 | 一般不行 | 可以 |
| 目标被删 | 不影响(数据还在) | 变成悬空链接,访问报错 |
ls -li 看 inode | 与目标相同 | 与目标不同 |
软链接更灵活,是日常用得最多的;硬链接更“底层”,适合需要“同一份数据多个等价入口”的场景。
如果一个文件正被某个进程打开着(比如一个还在运行的服务正写着日志),你 rm 掉它——目录项没了,ls 看不到了,但进程仍持有这个 inode,数据块不会回收,直到进程关闭那个文件描述符或退出。表现就是 df 显示磁盘还满着,但 du 又找不到大文件。
lsof | grep deleted # 找出被删除但仍被进程占用的文件这种情况,重启或重载相应服务(让它松开文件句柄)才能真正释放空间。
链接相关的操作陷阱
cp 默认会跟随软链接复制目标内容,要保留链接本身用 cp -P 或 cp -a。mv 一个软链接是移动链接本身。相对路径的软链接(如 ln -s ../data current)在被移动到别处后会失效——优先用绝对路径,或确认相对关系不变。删大文件后空间没释放,先用 lsof 配合 grep deleted 排查,别盲目重启。
| 误区 | 更稳妥的做法 |
|---|---|
以为 rm 立刻就把数据和空间释放了 | rm 删的是名字;链接计数归零、且无进程占用,空间才释放 |
| 把硬链接当“备份” | 硬链接和源是同一份数据,改一个另一个也变;要备份用 cp |
| 软链接用相对路径,然后移动它 | 移动后相对关系可能失效;用绝对路径或确认路径关系 |
| 磁盘满但找不到大文件 | 可能是被删但仍被进程占用,用 lsof 配合 grep deleted 排查 |
版权归属:Shuo Liu