Linux 软链接和硬链接详解:ln 命令背后的 inode 原理

Linux 软链接和硬链接详解:ln 命令背后的 inode 原理

1. 前言

Linux 中经常会看到链接文件,例如:

bash 复制代码
/bin -> /usr/bin
python -> python3
current -> /opt/app/releases/v2

Linux 链接主要有两种:

text 复制代码
软链接:symbolic link
硬链接:hard link

创建链接使用 ln 命令。

本文重点讲清楚:

  • inode 是什么;
  • 软链接是什么;
  • 硬链接是什么;
  • 二者有什么区别;
  • 删除源文件后分别会怎样;
  • 实际项目中怎么用。

2. inode 是什么

Linux 文件可以简单理解为两部分:

text 复制代码
文件名 + inode

文件名保存在目录中。

inode 保存文件的元数据和数据块位置。

inode 中常见信息包括:

  • 文件类型;
  • 权限;
  • 所属用户;
  • 所属用户组;
  • 文件大小;
  • 时间戳;
  • 数据块位置;
  • 硬链接数量。

查看 inode:

bash 复制代码
ls -i file.txt

查看详细信息:

bash 复制代码
stat file.txt

3. 硬链接是什么

硬链接可以理解为:

text 复制代码
多个文件名指向同一个 inode

创建硬链接:

bash 复制代码
ln source.txt hard.txt

查看:

bash 复制代码
ls -li source.txt hard.txt

可能输出:

bash 复制代码
123456 -rw-r--r-- 2 user user 100 source.txt
123456 -rw-r--r-- 2 user user 100 hard.txt

两个文件 inode 一样,说明它们本质上指向同一份文件数据。

修改任意一个:

bash 复制代码
echo "hello" >> hard.txt
cat source.txt

会发现内容也变了。


4. 删除源文件后硬链接还在吗

创建文件和硬链接:

bash 复制代码
echo "linux" > source.txt
ln source.txt hard.txt

删除源文件名:

bash 复制代码
rm source.txt

查看硬链接:

bash 复制代码
cat hard.txt

仍然可以读取内容。

原因是:

text 复制代码
rm 删除的是一个文件名,不是立即删除 inode 数据。
只要还有硬链接指向 inode,数据就还在。

只有硬链接数量变成 0,文件数据才会真正释放。


5. 软链接是什么

软链接也叫符号链接。

它更像快捷方式,保存的是目标路径。

创建软链接:

bash 复制代码
ln -s source.txt soft.txt

查看:

bash 复制代码
ls -l soft.txt

输出:

bash 复制代码
soft.txt -> source.txt

查看 inode:

bash 复制代码
ls -li source.txt soft.txt

可能看到两个 inode 不同。

这说明软链接是一个独立文件,只是里面保存了目标路径。


6. 删除源文件后软链接会怎样

创建软链接:

bash 复制代码
echo "hello" > source.txt
ln -s source.txt soft.txt

删除源文件:

bash 复制代码
rm source.txt

再访问:

bash 复制代码
cat soft.txt

会报错:

text 复制代码
No such file or directory

此时软链接还在,但目标路径不存在,所以它变成了断链。


7. 软链接和硬链接对比

对比项 软链接 硬链接
是否有独立 inode 有 没有,和源文件共用 inode
指向对象 路径 inode
能否跨文件系统 可以 通常不可以
能否链接目录 可以 普通用户通常不可以
删除源文件后 失效 仍可访问
类似概念 快捷方式 同一文件的多个名字
创建命令 ln -s ln

一句话总结:

text 复制代码
软链接指向路径,硬链接指向 inode。

8. ln 命令常用写法

创建硬链接:

bash 复制代码
ln source.txt hard.txt

创建软链接:

bash 复制代码
ln -s source.txt soft.txt

强制更新软链接:

bash 复制代码
ln -sfn /opt/app/releases/v2 /opt/app/current

常用参数:

参数 作用
-s 创建软链接
-f 强制覆盖
-n 把已有软链接当作普通文件处理
-v 显示过程

查看链接指向:

bash 复制代码
readlink soft.txt
readlink -f soft.txt

9. 为什么硬链接不能跨文件系统

硬链接指向 inode。

inode 编号只在当前文件系统内部有意义。

不同磁盘分区或不同文件系统中,inode 编号可能重复。

所以硬链接通常不能跨文件系统。

如果尝试跨文件系统创建硬链接,可能报错:

text 复制代码
Invalid cross-device link

软链接不受这个限制,因为它保存的是路径。


10. 为什么硬链接通常不能链接目录

如果允许普通用户随意给目录创建硬链接,可能形成目录循环。

这会让遍历、备份、删除都变得复杂。

所以普通用户通常不能给目录创建硬链接。

如果要链接目录,使用软链接:

bash 复制代码
ln -s /var/log logs

进入:

bash 复制代码
cd logs

实际上进入的是 /var/log。


11. 实际使用场景

11.1 版本切换

bash 复制代码
/opt/app/releases/v1
/opt/app/releases/v2
/opt/app/current -> /opt/app/releases/v2

切换版本:

bash 复制代码
ln -sfn /opt/app/releases/v1 /opt/app/current

这种方式常用于部署和回滚。

11.2 配置启用

Nginx 常见结构:

bash 复制代码
/etc/nginx/sites-available/demo.conf
/etc/nginx/sites-enabled/demo.conf -> ../sites-available/demo.conf

启用配置:

bash 复制代码
ln -s ../sites-available/demo.conf /etc/nginx/sites-enabled/demo.conf

11.3 避免重复存储

同一大文件需要多个名字时,可以用硬链接:

bash 复制代码
ln bigfile.dat backup_bigfile.dat

注意:修改任意一个都会影响同一份数据。


12. 常见问题

12.1 如何判断是不是软链接

bash 复制代码
ls -l file

如果开头是 l:

bash 复制代码
lrwxrwxrwx

就是软链接。

12.2 删除软链接会删除源文件吗

不会。

bash 复制代码
rm soft.txt

只删除软链接本身。

但要注意目录软链接后面不要随便加 / 后再 rm -rf,否则可能进入目标目录删除内容。

12.3 如何找同 inode 的硬链接

查看 inode:

bash 复制代码
ls -i file.txt

查找:

bash 复制代码
find /path -inum 123456

13. 小结

软链接和硬链接核心区别:

text 复制代码
软链接:指向路径
硬链接:指向 inode

常用命令:

bash 复制代码
ln source hardlink
ln -s source softlink
ls -li
stat file
readlink link
readlink -f link

选择建议:

text 复制代码
链接目录:用软链接
跨文件系统:用软链接
版本切换:用软链接
同一文件多个名字:可用硬链接
避免重复存储大文件:可用硬链接

理解 inode 后,Linux 文件、链接、删除、磁盘占用之间的关系会清楚很多。

相关推荐
小兔子12 分钟前
Linux 的 write 返回成功,数据到底落在哪了
linux
我命由我1234514 分钟前
Python 开发 - Python 项目部署(Windows 与 Linux)
java·linux·windows·后端·python·java-ee·python3.11
erzong23115 分钟前
Linux操作系统:基于环形队列&信号量实现多生产者多消费者的简易模型
linux·运维·服务器
小羊没烦恼!20 分钟前
TypedSql:在 C# 类型系统上实现一个 SQL 查询引擎
java·linux·运维·服务器·开发语言·数据库·mysql
星恒随风43 分钟前
Linux线程同步与互斥(二):从日志系统与线程池设计,到线程安全单例、可重入函数和死锁原理
linux·运维·状态模式
mengge.cloud1 小时前
1022小白入门教程(番外筑基)— nerdctl 容器基本功 + K8s 资源编写
linux·网络·云原生·容器·kubernetes·云计算·k8s
张小姐的猫1 小时前
【MySQL】表的约束
android·linux·服务器·数据库·c++·mysql·adb
无足鸟ICT1 小时前
【RHCA+】yum命令(查询、安装、升级和卸载软件包)
linux
kyle~1 小时前
数据结构 --- 无锁队列(Lock-Free Queue)
linux·数据结构·c++·多线程·并发
邪修king1 小时前
Re:Linux系统篇(三十六):进程间通信Chapter3:从匿名管道到命名管道:Linux 进程间通信实战(FIFO 深度解析)
linux·运维·服务器