登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux lsfd 的文件描述符号与inode号有什么区别

来源:17golang原创

时间:2026-10-31 05:26:18 494浏览 收藏

在 Linux 里,FD 和 INODE 都是整数,但它们回答的不是同一个问题:FD 是某个进程访问打开文件时使用的编号,INODE 是文件系统用来标识文件对象的编号。一个进程可以有多个 FD 指向同一个 inode,多个进程也可以分别拥有自己的 FD;反过来,socket 或匿名 inode 可能没有可以直接打开的普通路径。

官方地址:https://man7.org/linux/man-pages/man1/lsfd.1.html

因此,用 lsfd 排查文件句柄时,不要只看某一列的数字。把 PID、FD、TYPE、INODE 和 NAME 放在一起,才能判断是进程入口重复、文件对象共享,还是对象本来就没有普通路径。

FD 是进程里的访问入口,INODE 是文件对象的身份

文件描述符号通常是进程文件描述符表中的下标。进程调用打开文件或创建 socket 的接口后,内核会把一个较小的整数交给它;进程随后用这个整数进行读写、关闭或等待。这个编号只在对应进程的语境中有意义,另一个进程可以同时使用相同的 FD 数字,却指向完全不同的对象。

inode 则描述文件对象在文件系统中的身份和元数据关联。普通文件、目录和许多特殊对象可以通过 inode 号与设备号组合来定位。路径名不是 inode 本身:硬链接可以让多个路径名指向同一个 inode,而文件被删除后,只要仍有进程持有打开引用,对应对象仍可能继续存在。

字段回答的问题作用范围
FD这个进程用哪个编号访问对象?进程级
INODE它关联的是哪个文件系统对象?设备/文件系统对象级
NAME这个对象当前可读的名称或描述是什么?展示级,特殊对象可能没有普通路径
Linux lsfd 中进程文件描述符 FD、文件对象 inode 和名称之间的静态关系说明图
图1:FD 属于进程访问入口,INODE 属于文件对象;这是静态结构说明图,不是截图或运行证据。

先用固定输出列建立可读的排查记录

lsfd 的默认输出可能随版本变化。需要复制结果、写脚本或交接给同事时,建议显式指定输出列,把“谁打开了什么”固定成同一种阅读顺序。

# 固定关键列,避免依赖 lsfd 的默认列顺序
lsfd --output PID,COMMAND,FD,TYPE,INODE,NAME

# 只查看一个进程,并保留 FD 与 inode 的对应关系
lsfd --pid 2468 --output PID,COMMAND,FD,TYPE,INODE,NAME

# 需要机器读取时使用 JSON;脚本仍应按字段名取值
lsfd --json --pid 2468 --output PID,FD,TYPE,INODE,NAME

这几列可以按“进程 → 入口 → 对象类型 → 对象身份 → 展示名称”的顺序阅读。比如同一个 PID 下出现两个不同 FD,但 INODE 与 TYPE 相同,首先应考虑这两个入口是否引用了同一个对象,而不是把两个 FD 当成两个文件。

数字相同或不同,分别说明什么

判断 FD 和 inode 的关系时,最容易犯的错是把“两个数字相等”理解成“它们代表同一层对象”。它们来自不同的编号空间,不能直接比较数值大小或是否相等。

  • 同一 PID、不同 FD、同一 INODE:可能是同一进程重复打开同一个文件,也可能是复制描述符后形成的两个访问入口。还要结合 NAME、TYPE 和打开模式继续判断。
  • 不同 PID、FD 数字相同:这很正常,因为 FD 是每个进程自己的编号。只有同时比较 inode、类型、路径或 socket 信息,才能判断是否共享对象。
  • 不同路径、同一设备上的同一 INODE:常见于硬链接;路径名不同不代表底层文件对象不同。
  • 同一名称、不同 INODE:可能是文件被替换、重新创建,或者名称只是特殊对象的描述。排障时不能只凭字符串判断连续两次采样是同一个对象。

如果目标是追踪“哪个进程还占着某个文件”,优先按 INODE 与 NAME 交叉看;如果目标是追踪“一个进程打开了多少入口”,优先按 PID 和 FD 看。

socket 和匿名 inode 为什么没有普通文件路径

TYPE 不一定是 REG。socket、eventfd、timerfd、epoll 和其他内核对象都可以通过文件描述符参与系统调用,但它们不是磁盘上的普通文件,所以 NAME 可能显示类型、端点或匿名对象描述,而不是可进入的目录路径。

# 只列出非普通文件,便于查看 socket、管道和其他特殊对象
lsfd --filter 'TYPE != "REG"' --output PID,COMMAND,FD,TYPE,INODE,NAME

# 聚焦已从文件系统目录中删除、但仍被进程持有的对象
lsfd --filter 'DELETED' --output PID,COMMAND,FD,TYPE,INODE,NAME

看到没有常规路径的对象时,不要用“找不到文件”作为结论。应先看 TYPE 和 NAME 的语义,再决定是否需要检查进程、网络端点、namespace 或资源关闭逻辑。容器环境还可能因为权限和 namespace 视角不同而缺少部分关联信息。

Linux lsfd 中普通文件、已删除文件、socket 和匿名对象的分类关系说明图
图2:普通文件与特殊对象在 TYPE、INODE、NAME 上的观察差异,这是静态关系说明图,不是截图或运行证据。

把排查动作限制在明确的进程和字段上

排查句柄泄漏或删除后仍占用空间的问题时,先缩小进程范围,再固定字段,比直接阅读默认大表更安全。--pid 是按进程收集信息的入口;--filter 适合表达列条件,但同样的 PID 筛选通常更早发生,开销也更低。

# 按 PID 限定收集范围,适合已知服务进程的场景
lsfd --pid 2468 --output PID,COMMAND,FD,TYPE,INODE,NAME

# 只查看指定进程中的 socket 对象
lsfd --pid 2468 --filter 'TYPE == "UNIX-STREAM"' \
  --output PID,COMMAND,FD,TYPE,INODE,NAME,UNIX.PATH

# 显式指定列并使用原始格式,便于后续脚本处理
lsfd --raw --output PID,FD,TYPE,INODE,NAME

将结果用于脚本时,不要依赖默认列、空白切分或会变化的展示名称;优先使用显式列或 JSON 字段,并在记录中保留采集时的 PID、时间和筛选条件。这样下一次观察到 inode 变化时,才知道是对象被替换,还是进程已经重启。

一张速查表:看到什么就往哪边判断

观察到的组合优先解释下一步
同 PID,FD 不同,INODE 相同多个进程入口关联同一对象检查打开方式、复制描述符和关闭时机
不同 PID,FD 相同编号只是在各自进程内重复比较 INODE、TYPE 和 NAME,不比较 FD 数值
TYPE 不是 REG,NAME 无普通路径socket 或匿名内核对象读取对应类型字段,结合进程和 namespace 排查
DELETED 被标记目录项已删除但引用尚未释放确认哪个进程持有 FD,再检查服务关闭或轮换逻辑
同名对象的 INODE 发生变化路径可能被替换或重新创建把路径名和 inode 一起记录,避免误判为同一文件

最后可以把结论记成一句话:FD 说明“进程通过哪个入口访问”,INODE 说明“入口关联哪个文件对象”。在 lsfd 输出中,先按 PID 和 FD 看进程视角,再按 TYPE、INODE 和 NAME 看对象视角,基本就不会把两套编号混为一谈。

常见问题

FD 号和 inode 号会不会刚好相同?

可能出现相同的数值,但这只是两个编号空间的偶然重合,不能据此判断它们代表同一个东西。

为什么文件已经删除,lsfd 还能列出来?

删除通常先移除目录项;只要进程还持有打开引用,对象仍可能存在,DELETED 和 INODE 可以帮助定位持有者。

脚本应该使用默认输出吗?

不建议。为脚本显式指定 --output 列,或使用 JSON 并按字段名读取,避免默认列在不同版本中变化。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>