lsof(List Open Files)是 Linux 系统中一个功能强大的命令行工具,用于列出当前系统被进程打开的文件。由于 Linux 中“一切皆文件”(包括网络连接、设备、管道等),lsof 成为了系统管理和故障排查的利器。
下面是一个快速了解 lsof 命令的表格,然后我们会详细讲解其语法、场景和案例。
| 功能维度 | 命令示例 | 说明 |
|---|---|---|
| 🔍 定位文件占用 | lsof /path/to/file |
查看谁在占用某个文件或目录 |
| 📡 网络连接分析 | lsof -i :8080 |
查看指定端口的占用情况(TCP/UDP) |
| 🧟 查找僵尸文件 | `lsof~s | grep deleted` |
| 👤 用户行为追踪 | lsof -u username |
查看某用户打开的所有文件 |
| 📊 进程资源透视 | lsof -p PID |
查看某进程打开的所有资源 |
🔧 一、命令语法与核心选项
lsof 的命令格式可概括为:sudo lsof [筛选条件] [组合逻辑] [输出控制]。
常用选项速览
| 选项 | 含义 | 应用场景 |
|---|---|---|
-p PID |
指定进程ID | 查看特定进程打开的文件 |
-u user |
指定用户名 | 查看用户打开的文件 |
-c str |
命令名匹配 | 查看指定命令打开的文件 |
-i |
网络连接 | 查看网络连接与端口占用 |
+D dir |
递归扫描目录 | 查看目录中被打开的文件 |
-d FD |
文件描述符 | 查看指定FD的文件 |
-a |
逻辑"与" | 组合多个条件进行筛选 |
-t |
仅输出PID | 方便脚本处理,如 kill -9 $(lsof -t -i:8080) |
输出字段解析
lsof 输出包含多个信息丰富的字段,理解它们是有效诊断的关键:
| 字段 | 含义 | 诊断价值 |
|---|---|---|
| COMMAND | 进程名称 | 识别占用资源的程序(如nginx, java) |
| PID | 进程ID | 精准操作目标(kill, strace) |
| USER | 进程所有者 | 判断权限问题 |
| FD | 文件描述符 | 核心字段,表示文件与进程的关系 |
| TYPE | 文件类型 | REG(普通文件)、DIR(目录)、IPv4(网络套接字)等 |
| NAME | 文件路径/连接详情 | 关键定位信息 |
FD (文件描述符) 详解
FD 字段格式为 [访问权限][锁定状态]?[描述符类型]。
-
前缀字符:
r(读),w(写),u(读写)。 -
描述符类型: -
cwd:当前工作目录。 -txt:程序代码(二进制文件或库)。 -mem:内存映射文件。 -0u,1w,2u:标准输入、输出、错误。 -3u:普通文件描述符(自定义打开的文件)。 -
状态标记:
DEL(文件已删除但未释放),W(文件被写锁定)。
🎯 二、常见应用场景与案例
-
🔍 定位文件或目录占用 - 场景:无法卸载磁盘分区、删除文件时提示 "Device or resource busy"。 - 命令:
# 查看具体文件被谁占用 sudo lsof /path/to/file # 递归查看目录中所有被打开的文件 sudo lsof +D /path/to/directory- 案例:无法卸载/mnt目录。$ sudo lsof +D /mnt COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 1234 root cwd DIR 8,1 4096 2 /mnt/data解读:一个 bash 进程的当前工作目录(cwd)是/mnt/data,导致无法卸载。可切换该进程工作目录或终止进程。 -
📡 分析网络连接与端口占用 - 场景:服务启动失败,提示 "Address already in use";检查异常网络连接。 - 命令:
# 查看所有监听端口 sudo lsof -iTCP -sTCP:LISTEN -nP # 查看特定端口(如8080)占用 sudo lsof -i :8080 # 查看与指定IP(如10.0.0.5)的所有连接 sudo lsof -i @10.0.0.5 -n- 案例:排查 80 端口被谁占用。$ sudo lsof -i :80 -nP COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 123 nginx 6u IPv4 12345 0t0 TCP 192.168.1.1:80 (LISTEN)解读:nginx 进程(PID=123)正在监听 80 端口。 -
🧟 查找已删除但未释放的文件(空间泄漏) - 场景:
df显示磁盘空间不足,但du找不到大文件。通常是进程打开文件后,文件被删除,但进程未退出,空间未释放。 - 命令:# 查找所有已删除但未释放的文件 sudo lsof -nP | grep deleted # 统计某用户进程未释放的空间 (MB) sudo lsof -u appuser | grep deleted | awk '{sum+=$7} END {print sum/1024/1024 " MB"}'- 案例:磁盘空间告警。$ sudo lsof -nP | grep deleted java 9012 appuser 4w REG 8,1 1024000000 789012 /opt/app.log (deleted)解读:Java 进程(PID=9012)曾写入/opt/app.log(FD=4w),文件被删除但进程仍持有,占用了约 1GB 空间。解决:重启该 Java 进程可释放空间。 -
📊 透视进程资源使用 - 场景:排查进程文件描述符泄漏、监控进程行为。 - 命令:
# 查看特定进程(如PID为1234)打开的所有资源 sudo lsof -p 1234 # 动态监控进程FD数量变化(每2秒刷新) watch -n 2 "lsof -p 1234 | wc -l" # 查看指定命令(如java)打开的文件 sudo lsof -c java- 案例:监控一个服务进程的文件描述符数量是否持续增长(可能泄漏)。$ watch -n 2 "lsof -p 1234 | wc -l" # 观察输出数值是否随时间不断增加 -
👤 用户级资源审计 - 场景:统计用户打开文件数、检查特权用户操作。 - 命令:
# 统计各用户打开文件数并排序 sudo lsof -n | awk '{print $3}' | sort | uniq -c | sort -nr # 查看指定用户(如nginx)打开的文件 sudo lsof -u nginx # 检查root用户对敏感文件的操作 sudo lsof -u root | grep /etc/shadow
⚠️ 三、注意事项
-
权限问题:查看系统级或其它用户的进程信息通常需要
sudo权限,否则可能无法获取完整列表。 -
性能影响:在负载较高的系统上,使用
lsof遍历所有进程可能带来短暂性能压力。尽量使用过滤选项缩小范围,避免直接使用lsof > all.txt这样的全量扫描。 -
容器环境:在 Docker 环境中,宿主机上的
lsof可能无法直接查看容器内进程打开的文件。如需查看容器内情况,应在容器内执行lsof或使用docker exec -it container_name lsof。 -
输出解读:仔细阅读
FD,TYPE,NAME列信息,特别是文件描述符模式和状态标记(如deleted),这对定位问题至关重要。
💎 总结
lsof 是 Linux 系统管理和故障排查中不可或缺的工具,它帮助我们深入理解进程与资源间的关联。
掌握 lsof,能让你在遇到“文件无法删除”、“端口被占用”、“磁盘空间异常”等问题时,快速定位真相,从而高效地解决问题。希望以上的解释和案例能帮助你更好地使用它。
浙公网安备 33010602011771号