当前位置: 首页 > news >正文

深入理解 lsof:麒麟Linux 系统中查看打开文件的利器

#Linux  #麒麟  #lsof

在 Linux 系统中,"一切皆文件" 是核心设计理念之一。从普通文本到网络套接字,从设备驱动到管道,所有资源都以文件形式呈现。

管理这些 "文件" 对于系统运维、故障排查至关重要,而 lsof(List Open Files)就是一款专门用于列出系统中所有被进程打开的文件的强大工具。

本文将深入解析 lsof 的工作原理、常用功能及实战场景,帮助你掌握这一运维必备技能。

一、lsof 是什么?

lsof 是 "List Open Files" 的缩写,它能够列出系统中所有被进程打开的文件信息。这里的 "文件" 涵盖了以下类型:

  • 普通文件(文本、二进制文件等)
  • 目录
  • 设备文件(块设备、字符设备)
  • 网络文件(TCP 连接、UDP 套接字、网络端口等)
  • 管道(命名管道、无名管道)
  • 符号链接

lsof 通过解析 /proc 文件系统(进程信息伪文件系统)获取进程打开的文件描述符信息,进而展示进程与文件的关联关系。

它几乎是排查 "文件占用"" 端口冲突 ""资源泄漏" 等问题的首选工具。

二、lsof 的工作原理

Linux 系统中,每个进程在启动后会在 /proc/<PID>/fd 目录下创建文件描述符(File Descriptor),记录该进程打开的所有文件。例如,/proc/1234/fd/0 表示 PID 为 1234 的进程打开的标准输入(stdin)。

lsof 的工作流程如下:

  • 遍历系统中所有活跃进程(/proc 目录下的进程 ID 目录);
  • 读取每个进程的文件描述符信息(/proc/<PID>/fd);
  • 解析文件描述符对应的实际文件路径、类型、状态等;
  • 汇总并格式化输出结果,展示进程与文件的关联关系。

由于需要访问系统核心进程信息,lsof 通常需要 root 权限才能查看所有进程的完整信息(普通用户仅能查看自己的进程)。

三、核心功能与常用命令

lsof 的命令格式为:lsof [选项],默认情况下会输出所有进程打开的所有文件(内容较多),实际使用中需结合选项筛选。以下是最常用的功能及示例:

1. 查看特定进程打开的文件

选项:-p <PID>(指定进程 ID)

用途:分析某个进程正在读写的文件(如日志、配置文件、数据库文件等)。

#查看pg数据库的进程
pidof postgres
1848 1847 1846 1844 1843 1842# 查看 PID 为 1842的进程打开的所有文件
lsof -p 1842

输出结果

[root@db1 ~]# lsof -p 1848 
COMMAND   PID     USER   FD      TYPE DEVICE  SIZE/OFF     NODE NAME
postgres 1848 postgres  cwd       DIR  253,0      4096 20104278 /data/pgdata/data
postgres 1848 postgres  rtd       DIR  253,0      4096      128 /
postgres 1848 postgres  txt       REG  253,0  55109064 19922937 /usr/local/postgres/bin/postgres
postgres 1848 postgres  mem       REG   0,20   1048576    56387 /dev/shm/PostgreSQL.4284816928
postgres 1848 postgres  mem       REG  253,0     55496 50481071 /usr/lib64/libnss_files-2.28.so
postgres 1848 postgres  DEL       REG    0,5              56373 /dev/zero

2. 查看特定文件被哪些进程占用

用法:直接指定文件名或路径

用途:解决 "文件无法删除"" 设备忙 "等问题(如删除日志文件时提示"Device or resource busy")。

# 查看 /var/log/messages 被哪些进程打开
lsof /var/log/messages# 查看 /etc/passwd 被哪些进程访问
lsof /etc/passwd

若文件已被删除但仍被进程占用(常见于日志轮转场景),NAME 列会显示 (deleted) 标记,此时需重启相关进程释放资源。

3. 分析网络连接与端口占用

选项:-i(网络相关文件)

用途:排查端口冲突、异常连接、网络服务状态等问题,是网络排障的核心工具。

(一)列出所有网络连接(TCP/UDP)

[root@db1 data]# lsof -i
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd     1     root   46u  IPv6  27292      0t0  TCP *:websm (LISTEN)
rpcbind   873      rpc    6u  IPv4  26744      0t0  UDP *:sunrpc 
rpcbind   873      rpc    7u  IPv4  26745      0t0  TCP *:sunrpc (LISTEN)
rpcbind   873      rpc    8u  IPv6  26746      0t0  UDP *:sunrpc 
rpcbind   873      rpc    9u  IPv6  26747      0t0  TCP *:sunrpc (LISTEN)
chronyd   923   chrony    6u  IPv4  27988      0t0  UDP localhost:323 
chronyd   923   chrony    7u  IPv6  27989      0t0  UDP localhost:323 
sshd     1382     root    5u  IPv4  47971      0t0  TCP *:ssh (LISTEN)
sshd     1382     root    6u  IPv6  47973      0t0  TCP *:ssh (LISTEN)
sshd     1647     root    5u  IPv4  50044      0t0  TCP db1:ssh->192.168.74.1:59521 (ESTABLISHED)
sshd     1659     root    5u  IPv4  50044      0t0  TCP db1:ssh->192.168.74.1:59521 (ESTABLISHED)
postgres 1842 postgres    6u  IPv6  56382      0t0  TCP localhost:postgres (LISTEN)
postgres 1842 postgres    7u  IPv4  56383      0t0  TCP localhost:postgres (LISTEN)

(二)仅查看 TCP 连接(包括监听、已建立等状态)

[root@db1 data]# lsof -i tcp
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd     1     root   46u  IPv6  27292      0t0  TCP *:websm (LISTEN)
rpcbind   873      rpc    7u  IPv4  26745      0t0  TCP *:sunrpc (LISTEN)
rpcbind   873      rpc    9u  IPv6  26747      0t0  TCP *:sunrpc (LISTEN)
sshd     1382     root    5u  IPv4  47971      0t0  TCP *:ssh (LISTEN)
sshd     1382     root    6u  IPv6  47973      0t0  TCP *:ssh (LISTEN)
sshd     1647     root    5u  IPv4  50044      0t0  TCP db1:ssh->192.168.74.1:59521 (ESTABLISHED)
sshd     1659     root    5u  IPv4  50044      0t0  TCP db1:ssh->192.168.74.1:59521 (ESTABLISHED)
postgres 1842 postgres    6u  IPv6  56382      0t0  TCP localhost:postgres (LISTEN)
postgres 1842 postgres    7u  IPv4  56383      0t0  TCP localhost:postgres (LISTEN)
sshd     2641     root    5u  IPv4  64609      0t0  TCP db1:ssh->192.168.74.1:63744 (ESTABLISHED)
sshd     2644     root    5u  IPv4  64609      0t0  TCP db1:ssh->192.168.74.1:63744 (ESTABLISHED)

(三) 查看PG数据库5432端口被哪些进程占用(常用于解决"端口已被使用"错误)

[root@db1 data]# lsof -i :5432
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
postgres 1842 postgres    6u  IPv6  56382      0t0  TCP localhost:postgres (LISTEN)
postgres 1842 postgres    7u  IPv4  56383      0t0  TCP localhost:postgres (LISTEN)

(四)查看 22 端口的 TCP 连接(如 SSH 连接)

[root@db1 data]# lsof -i tcp:22
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1382 root    5u  IPv4  47971      0t0  TCP *:ssh (LISTEN)
sshd    1382 root    6u  IPv6  47973      0t0  TCP *:ssh (LISTEN)

(五)查看与 192.168.1.100 的网络连接

[root@db1 data]# lsof -i @192.168.74.46
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1647 root    5u  IPv4  50044      0t0  TCP db1:ssh->192.168.74.1:59521 (ESTABLISHED)
sshd    1659 root    5u  IPv4  50044      0t0  TCP db1:ssh->192.168.74.1:59521 (ESTABLISHED)
sshd    2641 root    5u  IPv4  64609      0t0  TCP db1:ssh->192.168.74.1:63744 (ESTABLISHED)
sshd    2644 root    5u  IPv4  64609      0t0  TCP db1:ssh->192.168.74.1:63744 (ESTABLISHED)

4. 查看特定用户打开的文件

选项:-u <用户名>
用途:监控用户活动,排查特定用户的进程资源占用。

查看用户 postgres 打开的部分文件

[root@db1 data]# lsof -u postgres | head -n 10
COMMAND   PID     USER   FD      TYPE             DEVICE  SIZE/OFF     NODE NAME
postgres 1842 postgres  cwd       DIR              253,0      4096 20104278 /data/pgdata/data
postgres 1842 postgres  rtd       DIR              253,0      4096      128 /
postgres 1842 postgres  txt       REG              253,0  55109064 19922937 /usr/local/postgres/bin/postgres
postgres 1842 postgres  mem       REG              253,0     55496 50481071 /usr/lib64/libnss_files-2.28.so
postgres 1842 postgres  DEL       REG                0,5              56373 /dev/zero
postgres 1842 postgres  mem       REG              253,0 215159920  3654424 /usr/lib/locale/locale-archive
postgres 1842 postgres  mem       REG              253,0    149736 50539780 /usr/lib64/libgpg-error.so.0.29.0
postgres 1842 postgres  mem       REG              253,0    604616 50509362 /usr/lib64/libpcre2-8.so.0.10.0
postgres 1842 postgres  mem       REG              253,0     14336 50480550 /usr/lib64/libsecurity.so.0.0.0

5. 递归查看目录下的文件占用

选项:+D <目录路径>

用途:分析某个目录(如网站根目录、数据目录)下所有文件的占用情况。

递归查看 /data/pgdata/data/ 目录下被打开的文件(包括子目录)

[root@db1 data]# lsof +D /data/pgdata/data/
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
postgres 1842 postgres  cwd    DIR  253,0     4096 20104278 /data/pgdata/data
postgres 1843 postgres  cwd    DIR  253,0     4096 20104278 /data/pgdata/data
postgres 1844 postgres  cwd    DIR  253,0     4096 20104278 /data/pgdata/data
postgres 1846 postgres  cwd    DIR  253,0     4096 20104278 /data/pgdata/data
postgres 1847 postgres  cwd    DIR  253,0     4096 20104278 /data/pgdata/data
postgres 1847 postgres    6u   REG  253,0     8192   964768 /data/pgdata/data/global/1262
postgres 1848 postgres  cwd    DIR  253,0     4096 20104278 /data/pgdata/data
postgres 1848 postgres    6u   REG  253,0        0   964778 /data/pgdata/data/global/6100
bash     2123     root  cwd    DIR  253,0     4096 20104278 /data/pgdata/data
lsof     2784     root  cwd    DIR  253,0     4096 20104278 /data/pgdata/data
lsof     2785     root  cwd    DIR  253,0     4096 20104278 /data/pgdata/data

与 -d 选项结合可进一步筛选文件类型(如 lsof +D /var/log -d txt 查看日志目录下的文本文件)。

6. 高级筛选:组合参数

lsof 支持多参数组合,通过 -a(逻辑与)实现精准筛选:

# 查看 root 用户的 TCP 连接(-u root 与 -i tcp 的交集)
lsof -u root -a -i tcp# 查看 nginx 进程占用的 443 端口(-c 匹配进程名前缀)
lsof -c nginx -a -i :443# 仅输出进程 ID(配合 kill 命令快速终止进程)
lsof -t -i :8080 | xargs kill -9

四、实战场景:解决实际问题

场景 1:端口被占用,无法启动服务

当启动服务时提示 "Address already in use",可用 lsof 快速定位占用端口的进程:

# 查找 8080 端口的占用进程
lsof -i :8080# 输出示例:
# COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
# java    1234  app   42u  IPv6  12345      0t0  TCP *:8080 (LISTEN)# 终止占用进程(根据 PID)
kill -9 1234

场景 2:删除文件后磁盘空间未释放

Linux 中,若文件被进程占用,删除后空间不会立即释放(需进程关闭文件)。用 lsof 可找到占用已删除文件的进程:

# 查找所有已删除但仍被占用的文件
lsof | grep deleted# 输出示例:
# rsyslogd  567  root    3w   REG    8,1  1048576  1234 /var/log/old.log (deleted)# 重启进程释放空间(或发送 SIGHUP 信号让进程重新打开文件)
systemctl restart rsyslog

场景 3:排查异常网络连接

发现服务器有异常外部连接时,用 lsof 分析连接来源和关联进程:

# 查看所有已建立的外部连接
lsof -i | grep ESTABLISHED# 定位连接到可疑 IP(如 203.0.113.5)的进程
lsof -i @203.0.113.5

场景四:排查挂载点占用

当卸载挂载点时提示 "target is busy",可用 lsof 快速定位占用挂载点的进程:

# 尝试卸载/dbsoft挂载点
umount /dbsoft 
umount: /dbsoft: target is busy.#查看占用/dbsoft的进程 
lsof /dbsoft/
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    2409 postgres  cwd    DIR  259,4       65  128 /dbsoft# 终止占用进程(根据 PID)
kill -9 2409 #卸载成功
umount /dbsoft

五、注意事项

  • 权限问题:普通用户只能查看自己的进程,查看系统级进程需用 sudo 或 root 权限。
  • 性能影响:lsof 遍历所有进程和文件描述符,在高负载系统(如进程数 > 10000)中可能耗时较长,建议避免频繁执行。
  • 输出解读:重点关注 COMMAND(进程名)、PID(进程 ID)、FD(文件描述符)、TYPE(文件类型)、NAME(文件路径 / 网络信息)。

六、总结

lsof 是 Linux 系统中功能强大的 "文件侦探",它不仅能列出进程与文件的关联,更能深入分析网络连接、资源占用等核心系统状态。掌握 lsof 的常用命令和实战技巧,能显著提升系统排障效率,解决端口冲突、文件占用、资源泄漏等常见问题。


🚀 更多数据库干货,欢迎关注【安呀智数据坊】

如果你觉得这篇文章对你有帮助,欢迎点赞 👍、收藏 ⭐ 和留言 💬 交流,让我知道你还想了解哪些数据库知识!

📬 想系统学习更多数据库实战案例与技术指南?

📊 实战项目分享

📚 技术原理讲解

🧠 数据库架构思维

🛠 工具推荐与实用技巧

立即关注,get知识抢先一步,持续更新中 👇


文章转载自:

http://1dTztklX.stsnf.cn
http://42TtTmXu.stsnf.cn
http://Uvh73rOi.stsnf.cn
http://0SGomAXP.stsnf.cn
http://hwYlNlLM.stsnf.cn
http://Bm4sOSwT.stsnf.cn
http://8ZUKGQcO.stsnf.cn
http://vXyq5npO.stsnf.cn
http://fk92LnWu.stsnf.cn
http://UThdjiNV.stsnf.cn
http://itWpZEYI.stsnf.cn
http://BNjaU2q7.stsnf.cn
http://KWwjiYkQ.stsnf.cn
http://KFA07F4q.stsnf.cn
http://X5FoiWgn.stsnf.cn
http://Vs5XU0oF.stsnf.cn
http://uvIG2o1x.stsnf.cn
http://d1ZOXSVh.stsnf.cn
http://92KoCziq.stsnf.cn
http://0opPaFPb.stsnf.cn
http://0Yorzlyo.stsnf.cn
http://etlLrRX4.stsnf.cn
http://JkFOWynP.stsnf.cn
http://riYrxwfj.stsnf.cn
http://e4F4So4p.stsnf.cn
http://vMucRgnX.stsnf.cn
http://YUNx4DsC.stsnf.cn
http://iZUKmKU7.stsnf.cn
http://c2R9dXts.stsnf.cn
http://Q2DUNs0N.stsnf.cn
http://www.dtcms.com/a/373368.html

相关文章:

  • B站 韩顺平 笔记 (Day 27)
  • 同星TSMaster软件安装
  • 【软件测试】入门基础
  • [Maven 基础课程]pom.xml
  • 算法之滑动窗口
  • 解决 GitHub SSH 连接超时问题
  • 服务器文件同步用哪个工具?介绍一种安全高效的文件同步方案
  • SOME/IP-SD(Service Discovery)协议的核心协议
  • Claude-Flow 使用指南
  • SpringMVC 工作原理
  • Oracle高可用与容灾解决方案
  • 玳瑁的嵌入式日记D33-0908(SQL数据库)
  • GISBox内置GIS服务器:从数据导入到场景化应用的全流程
  • 基于Python+Streamlit的旅游数据分析与预测系统:从数据可视化到机器学习预测的完整实现
  • 【硬件-笔试面试题-69】硬件/电子工程师,笔试面试题(知识点:电机驱动电路的反馈电路)
  • 【Ansible】实施 Ansible Playbook知识点
  • 汽车电子软件 --- 架构演进与挑战突破之路
  • 13、做中学 | 初一下期 Golang数组与切片
  • Linux系统:线程的互斥和安全
  • # 集成学习完整指南:从理论到实践
  • CSS rem单位
  • 云原生与 AI 加持下,DevOps平台的演进趋势、选型建议与推荐指南
  • 软件研发如何选对方法论?传统计划驱动与敏捷价值驱动的全面对比
  • CVE-2025-57052:cJSON库存在CVSS 9.8高危JSON解析漏洞(含PoC)
  • 基于大数据的二手交易推荐系统设计与实现(代码+数据库+LW)
  • 9.8 ajax+php基础语法
  • USB系统学习笔记 - 从概念到抓包解析
  • 前端框架对比分析:离线PWA + Cloudflare Workers部署
  • TensorFlow深度学习实战(37)——深度学习的数学原理
  • iOS混淆工具实战,健身与健康监测类 App 的隐私与算法保护