026 inode 与软硬链接

inode 与软硬链接

先说明一下前面没有解释的东西:文件权限后面的 1 是什么?

1. 概念

软链接是一个特殊类型的文件,它的内容是一个 路径字符串,指向原始文件的路径。

  • 就像 Windows 的 快捷方式;
  • 保存的是目标路径
  • 用途:可以在任何地方"引用"一个程序、配置文件、目录;
  • 常用于:
    • 给程序创建入口路径(比如 /usr/bin/python 链接到 /usr/bin/python3.11);
    • 让你在任意位置执行程序;
    • 多个配置环境之间切换。
特性 描述
inode 不一致 链接文件有自己的 inode,数据内容是"路径名"
可跨分区 因为只是保存路径字符串,不依赖 inode
可对目录使用 /usr/bin/python 链接到 /usr/bin/python3.11
不影响原文件 原文件不变,软链接只是一个指向的"引用"

2. 相关命令

bash 复制代码
ln -s 源文件或目录 软链接文件名
ln -s /真实路径/程序 /usr/local/bin/程序名
bash 复制代码
ln -s /usr/bin/python3 /usr/local/bin/python
# 相当于:给 /usr/bin/python3 创建一个快捷方式,命名为 python,放到 /usr/local/bin/,让你直接用 python 执行。
bash 复制代码
ls -li		# 显示文件的 inode 编号以及其它详细信息

删除软链接:

bash 复制代码
rm 软链接路径(快捷方式的名称)	
rm text			# 只删除test对应的软链接,不影响原文件!

3. 软链接断裂检测

软链接如果原始文件删除,会变成"悬挂链接"。

检测方法:

bash 复制代码
find . -type l ! -exec test -e {} \; -print			# 找出指向无效文件的软链接。

4. 使用场景

  • 配置文件切换(配置环境切换只改软链接)
  • 多版本程序切换(如 python2 ↔ python3)
  • 日志链接(如将 /var/log/nginx/access.log 链接到别的目录)

2. 硬链接(hard link)

1. 概念

所谓的建立硬链接,本质其实就是在特定目录的数据块中新增文件名和指向的文件的 inode 编号的映射关系!

  • 是给文件 起一个新名字 ,指向 同一个内容(inode)
  • 就像给一篇文章起了两个标题,内容一模一样;
  • 删除"原始文件"不会丢内容,因为还有另一个"标题"指向同一内容;
  • 不能跨分区,不能用于目录
特性 描述
inode 不一致 链接文件有自己的 inode,数据内容是"路径名"
可跨分区 因为只是保存路径字符串,不依赖 inode
可对目录使用· /usr/bin/python 链接到 /usr/bin/python3.11
不影响原文件 原文件不变,软链接只是一个指向的"引用"

2. 相关命令

bash 复制代码
ln 原文件 硬链接名
bash 复制代码
ln myfile.txt myfile2.txt			# myfile.txt 和 myfile2.txt 指向同一个 inode,内容完全一样。

删除硬链接:

bash 复制代码
rm myfile.txt		# 内容不会被删除,只是链接计数 -1,除非所有硬链接都删光,才会真的释放 inode 和数据块。

3. 使用场景

  • 保留日志数据:删除前先做一个硬链接
  • 防止误删重要配置文件
  • 建立多个文件名访问同一内容的"别名"

3. 对比总结表

特性 软链接 (Symbolic Link) 硬链接 (Hard Link)
指向目标 指向路径 指向 inode
是否可跨分区 ✅ 是 ❌ 否
是否可对目录使用 ✅ 是 ❌ 否
删除原文件是否失效 ✅ 会失效断裂(变为悬挂链接) ❌ 不会,不影响内容
inode 是否相同(共享) ❌ 否 ✅ 是
使用场景 环境切换、目录链接、动态路径引用 防止误删、节省空间

4. 软硬链接对目录能否使用的原理

任意一个文件,无论是目录,还是普通文件,都有 inode,目录里面保存的是:文件名和 inode 编号的映射关系。

1. 为什么硬链接不能对目录使用 ------ Linux 内核禁止对目录创建硬链接

bash 复制代码
ln /etc /tmp/etc_hardlink

会报错:

bash 复制代码
ln: hard link not allowed for directory		# 目录不允许硬链接
原因 1:防止目录结构循环

假设你可以对目录建立硬链接:

  • /dir1 是一个目录。
  • 你执行:ln /dir1 /dir2/hardlink_to_dir1

如果允许硬链接对目录,可能会使目录形成了循环结构(死循环,无限递归):

bash 复制代码
/dir1/hardlink_to_dir1/hardlink_to_dir1/...

这会导致什么?
  • lsfinddu 等递归命令无限循环、卡死。
  • 操作系统处理 ... 也将失去一致性。

所以:为避免目录树出现"死循环",Linux 内核从一开始就禁用对目录的硬链接。


2. 为什么软链接可以对目录?

软链接本质上是 一个路径字符串,系统通过解析路径再跳转过去,跟文件/目录本体无直接绑定。

bash 复制代码
ln -s /etc /tmp/etc_soft
cd /tmp/etc_soft

这样就没问题,软链接不会打破目录结构,也不会增加 inode 引用计数(每一个 inode 内部,都有一个叫做引用计数的计数器,表示有多少个文件名指向我自己),因此安全、灵活。


3. . .. 是目录硬链接的特例!

每个目录都有一个 . 和一个 .. 条目,他们其实硬链接!为什么?

1. . 是当前目录的硬链接

  • 每个目录都需要能指向"自己"。
  • 所以 . 实际上就是 指向本目录 inode 的硬链接
  • 在文件系统中,这让程序在目录内操作时可以引用"当前目录"。

例如:cd . 其实就是进入当前目录,操作的就是 . 所指向的那个 inode


2. .. 是父目录的硬链接

  • 为了从当前目录 返回上一级目录,需要有个入口。
  • 所以 .. 就是一个 指向父目录 inode 的硬链接
  • 执行 cd .. 时,系统读取 .. 所指向的 inode,从而跳转到父目录。

3. 这两者是"硬链接",而不是软链接,原因很简单:

  • 它们存储的是 inode,不是路径字符串。
  • 所以当父目录名或当前目录名被改了,... 依然有效(不像软链接那样容易失效)。

所以每个目录的 ... 是硬链接,是因为它们直接存储 inode 号,这样能让系统通过 inode 来维护目录结构,确保文件系统高效且可靠地定位目录关系。

目录项 说明
. 当前目录的硬链接,指向本目录 inode
.. 父目录的硬链接,指向父目录 inode

这也是为什么:

  • 创建一个目录,其 链接数默认为 2. + 父目录中的它一次)
  • 每新增一个子目录,父目录的硬链接计数 +1(因为子目录的 .. 指向父目录)

示意图:

arduino 复制代码
/home
 └── user
      ├── .   -> /home/user
      ├── ..  -> /home
      └── doc
           ├── .. -> /home/user

但这是系统创建时 自动维护的结构 ,是 特权性操作 ,而 用户不能手动对目录建立普通硬链接


5. 小结

  • 软链接 = 快捷方式,路径引用,灵活,常用在程序入口/配置切换上
  • 硬链接 = 一个文件多个名字,共享内容,适合防误删、备份节省空间

想在终端任意地方运行程序,用 软链接 就行!

问题 解释
为什么硬链接不能用于目录? 为防止目录循环,系统不允许用户对目录建立硬链接
. .. 是硬链接吗? 是的,是系统自动创建并维护的特殊硬链接(特例)
为什么软链接能对目录? 因为它只是路径跳转,逻辑上没有破坏目录结构
相关推荐
路多辛42 分钟前
Debian新一代的APT软件源配置文件格式DEB822详解
linux·运维·ubuntu·debian
-VE-1 小时前
Linux线程控制
linux
驱动探索者1 小时前
USB ADB 简介
linux·adb·驱动·usb
dessler3 小时前
Hadoop HDFS-部署和基本操作
linux·运维·hdfs
风静雪冷3 小时前
find命令解读
linux
₯㎕星空&繁华5 小时前
Linux-地址空间
linux·运维·服务器·经验分享·笔记
小米里的大麦5 小时前
023 基础 IO —— 重定向
linux
风铃7775 小时前
c/c++ Socket+共享内存实现本机进程间通信
linux·c语言
lsnm7 小时前
【LINUX网络】HTTP协议基本结构、搭建自己的HTTP简单服务器
linux·运维·服务器·c语言·网络·c++·http