首页/新闻资讯/正文详情

Linux lsof命令详解:从原理到实战排查端口、进程与磁盘问题

发布时间:2026/9/24 19:21:36 来源:云帆数科 栏目:资讯中心
Linux lsof命令详解:从原理到实战排查端口、进程与磁盘问题
搞Linux运维和开发的朋友肯定都跟lsof这个命令打过交道。它全称是list open files专门用来列出当前系统中所有被进程打开的文件。在 CentOS 7.6 这套经典的老牌服务器系统上lsof可以说是排查网络、磁盘、进程问题的首选利器服务端口起不来、文件删不掉、磁盘空间莫名被占、连接数异常飙升这几种日常最头疼的场景靠它基本都能快速定位到“元凶”。这篇文章我就把lsof的底层原理、高频参数、实战排障思路和踩坑经验一次讲透不管是刚入门的运维新手还是写代码的开发者都能照着拿去用。1. 核心概念与工作原理先搞懂 lsof 到底在做什么1.1 一切皆文件lsof 就是在列这份清单Linux 世界里最基础也最核心的设计哲学就是“一切皆文件”。普通文件、目录算文件块设备、字符设备算文件网络套接字socket算文件管道、Unix 域套接字也算文件。这句话往深了说就是进程的任何输入输出动作本质都是在对文件描述符做操作。而lsof的工作就是把进程和它正在操作的这些“文件”之间的对应关系全部列出来相当于给整个系统做一次“文件占用全景扫描”。理解了这一点你就明白为什么lsof能查网络连接、能查端口监听、能查磁盘挂载情况了。很多人以为lsof只是个“查端口被谁占用的命令”其实它的能力远不止于此。它可以看到一个进程加载了哪些动态库、打开了哪些日志文件、当前工作目录在哪甚至能看到进程删掉但依然占着磁盘空间的文件。1.2 输出字段逐列拆解看懂 lsof 输出的每一列执行lsof后默认输出大概长这样COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1023 root cwd DIR 253,0 4096 2 / sshd 1023 root rtd DIR 253,0 4096 2 / sshd 1023 root txt REG 253,0 852856 853 /usr/sbin/sshd逐列看下来COMMAND是进程名PID是进程IDUSER是运行进程的用户NAME是文件或设备的完整路径。重点要理解的是FD和TYPE这两列因为排障时信息量最大。FD列表示文件描述符常见的有这几类cwd进程当前工作目录一般是一个DIR类型。txt进程的可执行文件本体也就是程序文件本身比如/usr/sbin/sshd。mem进程映射到内存中的文件通常是动态库比如/lib64/libc.so.6。数字加字母比如3u、4w、5r数字是文件描述符编号后面的u是可读可写r是只读w是只写。这种一般是进程主动打开的文件、日志或 socket。DEL文件已经被删除但还被进程占着这是磁盘空间排障时的关键线索。0u、1u、2u分别对应标准输入、标准输出、标准错误熟悉编程的人一眼就能看懂。TYPE列表示文件类型常见值有REG普通文件。DIR目录。CHR字符设备文件。BLK块设备文件。IPv4/IPv6网络连接对应 TCP 或 UDP socket。unixUnix 域套接字常用于本机进程间通信。FIFO管道文件。只要你把这两列看熟了lsof的输出就已经从“天书”变成了“索引表”。1.3 数据来源为什么 lsof 能看到别的进程的信息lsof之所以强大离不开 Linux 的/proc虚拟文件系统。系统内核会把每个进程的运行状态映射到/proc/PID/目录下其中/proc/PID/fd/里存放着该进程所有已经打开的文件描述符符号链接/proc/PID/maps里记录着内存映射的文件/proc/PID/cwd指向工作目录。lsof本质上就是在遍历这些 proc 条目把符号链接指向的真实文件路径解析出来再结合系统的挂载表、网络连接表等信息做汇总。所以理论上只要权限足够它能列出系统上所有进程的文件打开情况。这也是为什么普通用户执行lsof总会缺一些信息、而root能看到全部内容的原因——/proc里很多条目对普通用户是受限的。2. 高频参数拆解这些组合是日常排查的“万能钥匙”2.1 按端口和网络查询-i 参数的正确打开方式最经典的用法就是查端口占用lsof -i:8080这条命令会列出所有与 8080 端口相关的网络连接包括监听状态和已建立的连接。但这里有几个隐藏细节容易踩坑。第一个细节是端口匹配范围。lsof -i:8080匹配的是端口号但如果系统里有 IPv6 连接你可能会看到[::1]:8080这样的地址。多数情况下这没问题但如果你想只看 IPv4可以使用lsof -i4:8080同理想只看 IPv6 就用lsof -i6:8080。第二个细节是协议过滤。默认会同时显示 TCP 和 UDP 的结果。如果只想看 TCPlsof -iTCP:8080不过这里要提醒一句-iTCP会把监听和已建立的连接都列出来如果你的目的是排查“8080 到底被谁监听导致服务起不来”建议加上状态过滤。配合-s参数可以指定协议状态lsof -iTCP:8080 -sTCP:LISTEN这样输出就只保留监听状态的连接简洁明了一眼就能锁定占用进程。另外我自己常用的组合是加-P -n意思是不解析端口名和主机名lsof -i:8080 -P -n默认情况下lsof 会把 80 端口显示成http会尝试把 IP 反解成主机名这很拖慢速度而且生产环境通常也解析不了内网 IP。加了-P -n之后所有地址都以数字形式直出速度快得多脚本处理起来也方便。2.2 按进程、用户、目录查询精确锁定目标按进程 ID 查lsof -p 1234这会把 PID 为 1234 的进程打开的所有文件全部列出来。调试自己写的服务时非常有用比如看它到底读取了哪个配置文件、日志写到哪个文件去了。按进程名查lsof -c java-c后面跟的是进程名的前缀会匹配所有以 java 开头的进程。注意它是前缀匹配-c ssh会把sshd、ssh-agent都列出来。如果你只想精确匹配可以配合正则或者直接先用pgrep找到 PID 再用-p。按用户查lsof -u nginx这个会列出所有由 nginx 用户运行进程打开的文件。用来观察某个服务账号到底访问了哪些资源非常管用。还可以用^做排除比如lsof -u ^root就是列出所有非 root 用户进程打开的文件做安全审计的时候偶尔会用到。按目录查lsof D /var/log注意这里的D是大写意思是递归列出/var/log目录下所有被打开的文件。小写d只列当前目录不递归。这个命令在排查“日志目录里某个文件为什么删不掉”的时候很好使。不过要小心如果目录层级非常深、文件非常多D的扫描时间会明显变长线上环境谨慎使用。2.3 多条件组合-a 参数才是真正的杀手锏多个筛选条件放在一起时lsof默认是“或”的关系。比如lsof -p 1234 -i:8080这个命令的实际含义是“PID 为 1234 的进程打开的文件加上所有使用 8080 端口的连接”两组结果是并集。很多人刚接触时会误以为这是“PID 为 1234 的进程中使用 8080 端口的连接”其实不是。如果你想要“且”的关系必须显式加上-a参数lsof -a -p 1234 -i:8080加上-a之后输出就只剩下“PID 为 1234 的进程里使用 8080 端口的连接”了。这是一个非常容易忽略但实战价值极高的参数。排查“某个进程到底有没有监听某个端口”时-a -p PID -i:端口就是最精准的写法。这里我习惯再加一个-P -n完整命令是lsof -a -P -n -p 1234 -i:8080输出干净利落没有多余的域名解析过程。3. 实战场景实录六个最常见的排障案例3.1 场景一端口被占用服务启动失败这是lsof最出圈的一个场景。比如我遇到过 Java 服务启动时报Address already in use第一反应就是找端口被谁占了lsof -i:8080 -P -n输出里有一个java进程的 PID再看FD列是47uTYPE列是IPv4状态是LISTEN基本就能确认是它占用的。这时候有三种处理路径如果是历史残留的僵尸进程直接kill -9 PID清掉如果是正常的双实例部署那就得改端口配置或者做负载均衡如果是端口冲突还需要看一下是哪个服务配置里写死了这个端口。这里顺便提醒一句有些服务启动时绑定端口用的是SO_REUSEPORT特性允许多个进程同时监听同一端口这时候lsof会列出多条LISTEN记录不要看到第一条就急着 kill。3.2 场景二文件删不掉提示 “Text file busy”有时候你想删一个可执行文件系统直接告诉你Text file busy意思是有进程正在运行这个程序。用lsof一查就清楚了lsof /usr/local/bin/myapp输出里会显示是哪个进程正在执行这个文件FD列通常是txt。这种情况的正确做法是先停掉对应服务再删除文件。特别是升级二进制程序的时候很多人习惯先覆盖再删旧的碰到“删不掉”就懵了。其实lsof /path/to/file永远比fuser -k更稳妥因为你能先看到是哪个进程、哪个用户在运行它再决定要不要动。3.3 场景三磁盘空间明明被占df 和 du 对不上这个场景我觉得是lsof最能体现价值的地方也是很多老运维会心一笑的经典案例。排查流程是这样的df -h显示/根分区用了 95%但你du -sh /一层层往下找累计大小却远小于df的结果磁盘空间“凭空消失”了。原因通常是某个进程打开了一个大日志文件然后日志被rm删除了但进程还在持续往这个已删除的文件句柄里写数据。Linux 下文件被删除后如果还有进程持有文件描述符磁盘空间不会立即释放而是等进程关闭文件句柄或进程退出后才回收。排查手段很简单lsof | grep deleted这条命令会列出所有“已删除但仍被占用”的文件SIZE/OFF列会显示文件大小。根据文件路径就能定位到是哪个日志然后重启对应服务或者让进程重新加载日志句柄磁盘空间立刻就能释放。我在 CentOS 7.6 上处理过好几次这类问题元凶基本都是 Java 服务的 logback 日志或 Nginx 的 access.log因为习惯用rm清日志而不是用truncate -s 0清空日志。这里也分享一个预防习惯清日志尽量用 /var/log/xxx.log或truncate -s 0 /var/log/xxx.log而不要直接rm这样即使进程占着句柄文件本身还在不会造成“空间神秘失踪”。3.4 场景四排查进程到底打开了哪些文件写代码时经常需要确认程序是不是读了某个配置文件、日志是否写到预期目录。这种场景不需要翻代码直接看进程lsof -p 3221比如排查 Nginx 的 worker 进程输出里能看到cwd指向了 Nginx 的编译目录mem指向加载的各类.so动态库txt指向 nginx 二进制本体还有一堆REG类型的日志文件。通过这些信息你能直观地确认“这个进程当前真正在用的资源”是不是和你预想的一致。有时候程序的行为很反直觉你以为它读了/etc/myapp/config.ini其实它加载的是/opt/myapp/config.ini。lsof -p PID一梭子下去所有真实路径全部现形比看代码猜路径高效得多。3.5 场景五查看某个目录下文件被哪些进程访问比如线上排查配置文件被谁频繁修改或者想确认是否可以安全卸载某个挂载点直接用lsof /data或者递归查看整个目录lsof D /data这个命令会列出所有打开/data目录下文件的进程。典型应用场景是 NFS 或磁盘卸载前检查umount老提示target is busy怎么都卸载不掉就是有进程占着这个挂载点下的文件。用lsof D /data找到进程停掉之后再umount就能顺利执行。3.6 场景六连接数异常飙升快速统计和定位当某个服务连接数异常增多先统计各进程的 TCP 连接数lsof -iTCP -P -n | awk /ESTABLISHED/ {print $1, $2, $9} | sort | uniq -c | sort -rn这条管道命令的思路是lsof -iTCP -P -n列出所有 TCP 连接awk过滤出ESTABLISHED状态并提取进程名、PID、连接地址sort | uniq -c按进程分组计数最后sort -rn按数量从大到小排列。输出之后哪个进程连接数异常一眼就能看出来再往下就用lsof -iTCP -P -n | grep PID去细看具体连接对端 IP判断是不是被扫了端口或者服务被大量调用。4. 常见问题与避坑指南这些坑我基本都踩过4.1 报错 “lsof: command not found” 怎么办CentOS 7.6 的最小化安装默认不带lsof需要手动安装yum install -y lsof如果连 yum 源都没配置可以先将 CentOS 默认的 Base 源、Extras 源调整成可用状态再执行安装。安装后验证一下lsof -v能正常输出版本信息就说明装好了。这里也提醒一句很多生产服务器安全基线要求最小化安装所以换一台新机器先跑lsof发现没有命令是常态不用慌装上就行。4.2 普通用户执行 lsof 输出不全lsof对权限敏感。普通用户只能看到自己有权访问的进程信息其他用户进程的文件打开情况会直接被过滤掉。如果是在排查全局端口占用、磁盘空间问题时建议用root执行或者加sudosudo lsof -i:8080我遇到过不少新手在普通用户下执行lsof -i:80结果啥都没有误以为端口没被占用然后反复重启服务折腾半天。其实只要sudo lsof -i:80就能看到是 Apache 或 Nginx 在监听。排查网络类问题时尽量一开始就用 root 权限省去无谓的怀疑。4.3 lsof 输出慢或者卡住的原因在目录非常庞大比如/、或者有 NFS 网络挂载的情况下lsof会明显变慢因为它需要遍历大量目录并解析文件路径。这种时候有两个优化思路。第一个是缩小范围避免从全局lsof开始排查先用-p指定 PID 或用-i指定端口让 lsof 只做精确匹配。第二个是给网络查询加上-P -n不做端口名和主机名解析速度会快不少。对于 NFS 挂载点如果那个网络文件系统响应慢lsof D可能阻塞很久这种场景建议不要递归扫描 NFS 目录改用lsof /挂载点或者直接在 NFS 服务端排查。对了还有一个细节lsof空跑会尝试扫描 GPU 设备、伪终端等特殊文件这会拖慢输出。如果只是排查普通文件/网络问题不用管但如果感觉很慢可以先跑lsof -b跳过那些阻塞类型的扫描。-b参数的意思是避免进入内核无法访问的目录或设备在某些环境下有奇效。4.4 lsof -i 看到很多“奇怪的进程”其实是你没过滤状态lsof -i:6379可能会显示一堆CLOSE_WAIT、TIME_WAIT状态的连接尤其是高并发的 Redis 或 MySQL 服务上。如果你只想看谁在监听端口请一定带上-sTCP:LISTENlsof -i:6379 -sTCP:LISTEN -P -n同理想抓取所有“已建立”的连接lsof -i:6379 -sTCP:ESTABLISHED -P -n掌握这个过滤技巧之后查端口占用的效率会提升一大截不会被满屏的连接状态干扰视线。4.5 没有 lsof 时的替代方案某些精简容器镜像里没有lsof也装不了 yum 包这时候可以用ss和fuser做应急替代ss -lntp | grep 8080 fuser -v /path/to/filess -lntp输出里能看到监听端口的进程 PIDfuser -v能列出使用某个文件或目录的进程。但这两个工具的覆盖范围不如lsof全面比如“查已删除但还被进程占用的文件”就得靠lsof | grep deletedss和fuser都做不到。所以在日常 CentOS 7.6 环境里lsof依然是最值得装好的排障工具。5. 常用参数速查与组合记忆技巧为了不让你每次用的时候都要翻 man 手册我把高频参数整理成了一份速查表可以直接截图保存或者贴在工位上。参数作用典型用法-i:端口列出与该端口相关的网络连接lsof -i:3306-iTCP:端口只看 TCP 协议lsof -iTCP:3306-iUDP:端口只看 UDP 协议lsof -iUDP:53-sTCP:LISTEN只看监听状态lsof -iTCP:3306 -sTCP:LISTEN-p PID按进程 ID 查lsof -p 1234-c 名称按进程名前缀查lsof -c nginx-u 用户按用户查lsof -u www-u ^用户排除某个用户lsof -u ^rootd 目录列出目录下被打开的文件不递归lsof d /tmpD 目录递归列出目录下被打开的文件lsof D /var/log-a多个条件取“且”关系lsof -a -p 1234 -i:8080-P不解析端口名lsof -i:80 -P-n不解析主机名lsof -i -n-p 不生效的避免扫描阻塞设备lsof -b管道过滤查找已删除但被占用的文件lsof | grep deleted组合记忆技巧其实就三个套路查网络相关lsof -i开头按需追加TCP、:端口、-sTCP:LISTEN、-P -n。查进程相关lsof -p PID或lsof -c 名称配合-a可以再叠加其他条件。查文件相关直接lsof 文件路径搜目录用D搜被删文件用grep deleted。这三个套路覆盖了日常 90% 的排障需求。真正到线上执行的时候不用背太多冷门参数先把这几个组合练熟已经能解决绝大多数实际问题了。我自己用下来还有一个习惯如果一条 lsof 命令的输出特别长我不会直接翻屏幕而是先| head -30只看前 30 行再决定要不要全文分析。另外在脚本里调用lsof时一定要加上-P -n不然有概率因为 DNS 解析拖慢脚本执行这在批量排查几百台机器时差别特别明显。最后再说一个容易被忽略的小技巧lsof本身也支持监听模式用-r参数可以每隔几秒重复输出一次结果。比如lsof -i:8080 -r 3每 3 秒刷新一次端口占用情况适合观察端口是否有波动、或者服务重启过程中端口状态的变化。调试服务启动流程时非常实用不用一遍遍手动敲命令了。

相关推荐

Flutter跨平台开发实战:日期星期查询器鸿蒙适配指南
Flutter跨平台开发实战:日期星期查询器鸿蒙适配指南

最近把一个“日期星期查询器”的小工具用 Flutter 重写了一遍,顺手跑到了鸿蒙设备上。表面上看,这只是一个输入日期、返回星期几的简单应用,但真正做下来才发现,Flutter 的跨平台能力、鸿蒙生态的适配细节、日期计算的底层逻辑&am… · 2026/9/24 19:21:30

AI文本可视化工具实测:从思维导图到PPT大纲的适用边界
AI文本可视化工具实测:从思维导图到PPT大纲的适用边界

前几周我花了不少时间,把 PicDoc 这个 AI 文本可视化工具从头到尾折腾了一遍。从日常办公的文档处理,到自媒体内容的图文排版,再到给项目做汇报材料,我都拿它实际跑了几轮。结论放在前面:PicDoc 确实是一个有明确适用边… · 2026/9/24 19:21:30

微信小程序驾校预约管理系统源码解析与部署实战
微信小程序驾校预约管理系统源码解析与部署实战

简介:微信小程序的驾校预约管理系统是一套完整的98分毕业设计源码,经导师指导并认可通过,适合计算机、电子信息工程、数学等专业学生用于毕业设计、课程设计或期末大作业,也适合需要真实项目实战练手的学习者。系统基于Java技术栈… · 2026/9/24 19:21:30

数据中心供配电系统设计:从UPS选型到冗余架构与运维实践
数据中心供配电系统设计:从UPS选型到冗余架构与运维实践

供电这事儿,放在普通写字楼里可能就是“电闸别跳、电梯别停”的级别,但搁在数据中心里,那就是整个数字世界的命根子。你手机里的每一笔支付、云端存的每一张照片、AI模型每一次推理,背后都靠数据中心的服务器在扛,而服… · 2026/9/24 21:02:15

AI前端流式处理实战:SSE与WebSocket选型及TypeScript类型安全
AI前端流式处理实战:SSE与WebSocket选型及TypeScript类型安全

1. 这不是“前端面试题”,而是AI时代前端工程师的生存切口“最后提醒一次,9月的AI前端面试不用太老实”——这句话在技术社区刷屏时,我正用一个300行的Vue组件,把SSE流式响应拆解成逐字动画、带思考停顿的打字机效果,同… · 2026/9/24 21:02:15

老板算笔账:不做报表整合,你每年白养几个人
老板算笔账:不做报表整合,你每年白养几个人

老板们,先别算数字化能带来多少增长,先算算你正在为"不做"这件事,每天赔多少钱👇🔴 不做报表整合,你的团队在干嘛?每个月月底,你以为你的员工在干啥?❌ 从ERP导… · 2026/9/24 21:02:15

AI前端流式交互全链路:SSE、WebSocket与TypeScript实战
AI前端流式交互全链路:SSE、WebSocket与TypeScript实战

1. 这不是“前端面试题”,而是AI时代前端工程师的生存切口“最后提醒一次,9月的AI前端面试不用太老实”——这句话在技术社区刷屏时,我正给一个刚被大厂AI中台拒掉的前端同学复盘。他写了300行React TypeScript封装的ChatUI组件,… · 2026/9/24 21:02:15

本地部署大模型推理全指南:Ollama选型、硬件配置与API调用实战
本地部署大模型推理全指南:Ollama选型、硬件配置与API调用实战

1. 先算一笔账:本地跑大模型,到底省了哪笔钱 先说结论:本地部署大模型推理的核心价值,不只是省下 API 调用费,而是把“每次请求都按 token 付费”的模式,变成“一次买断硬件性能、之后随便用”的模式。 很… · 2026/9/24 21:02:09

RDMA门铃机制与GPU直通:两跳聚合与IBRC调优
RDMA门铃机制与GPU直通:两跳聚合与IBRC调优

1. 门铃机制与两种数据搬运模型:CPU-controlled vs GPU-initiated1.1 网卡“门铃”到底在响什么先说说标题里那个“门铃”是个什么梗。用过RDMA的人都知道,发送数据这活儿并不是你写完内存就能自动发出去的——你得往网卡里丢一个“doorbell”&#xff0… · 2026/9/24 21:02:09

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码