引言
lsof(List Open Files)是 Linux 系统管理员手中最强大的诊断工具之一。在 Linux 中,”一切皆文件”——普通文件、目录、网络套接字、管道、设备文件等都被视为文件。lsof 可以列出当前系统中所有被打开的文件,是定位连接问题、排查资源泄漏、分析进程行为的必备利器。
本文将全面介绍 lsof 的安装、基本用法、高级技巧及实战场景。
安装 lsof
大多数 Linux 发行版默认已安装 lsof,若未安装:
1 2 3 4 5 6 7 8
| sudo apt install lsof -y
sudo dnf install lsof -y
apk add lsof
|
验证安装:
基础用法
1. 列出所有打开的文件
输出结果很多,建议使用其他选项过滤。输出字段说明:
| 字段 | 含义 |
| COMMAND | 打开文件的进程名 |
| PID | 进程 ID |
| TID | 线程 ID(如果适用) |
| USER | 进程所有者 |
| FD | 文件描述符(cwd/rtd/txt/mem/数字等) |
| TYPE | 文件类型(REG/DIR/CHR/IPv4/0000等) |
| DEVICE | 设备号 |
| SIZE/OFF | 文件大小或偏移量 |
| NODE | 索引节点号 |
| NAME | 文件路径或连接信息 |
2. 查看特定用户打开的文件
1 2
| lsof -u username lsof -u xinyu
|
排除某个用户:
3. 查看特定进程的文件
1 2 3 4 5
| lsof -p PID lsof -p 1234
lsof -p 1234,5678
|
4. 查看特定端口的进程
1 2 3 4 5
| lsof -i :80
lsof -i :1-1024
|
5. 查看特定协议的连接
1 2 3 4 5 6 7 8 9
| lsof -i TCP
lsof -i UDP
lsof -i 4 lsof -i 6
|
6. 查看特定状态的口
1 2 3 4 5
| lsof -i TCP -s TCP:LISTEN
lsof -i TCP -s TCP:ESTABLISHED
|
常用选项详解
| 选项 | 作用 | 示例 |
-i | 显示网络连接 | lsof -i :443 |
-p | 按 PID 过滤 | lsof -p 1000 |
-u | 按用户过滤 | lsof -u nginx |
-c | 按命令名过滤 | lsof -c nginx |
-d | 按文件描述符过滤 | lsof -d 1-5 |
-t | 仅输出 PID(用于脚本) | lsof -t -i :80 |
+D | 递归列出目录下所有打开的文件 | lsof +D /var/log |
-r | 重复模式(刷新),n 秒后再次执行 | lsof -r 5 -i :443 |
-n | 不执行 DNS 反向解析(加快速度) | lsof -n -i |
-P | 不将端口号转换为服务名 | lsof -P -i |
-s | 按协议状态过滤 | lsof -i TCP -s TCP:LISTEN |
-F | 机器可解析的输出格式 | lsof -F pcfn -i :80 |
实战场景
场景 1:查看端口被哪个进程占用
这是最常用的场景——启动服务时发现端口已被占用:
1 2 3 4 5 6 7 8 9 10
| lsof -i :80
lsof -t -i :8080 kill -9 $(lsof -t -i :8080)
|
场景 2:找出文件被哪个进程使用
当需要卸载文件系统或删除文件时,报错”设备或资源忙”:
1 2 3 4 5 6 7 8
| lsof +D /var/log
lsof /var/log/nginx/access.log
lsof | grep /var/log | head -20
|
场景 3:监控网络连接
1 2 3 4 5 6 7 8
| lsof -r 3 -i :443
lsof -i TCP -s TCP:ESTABLISHED
lsof -nP -i TCP -s TCP:LISTEN
|
场景 4:诊断数据库连接问题
1 2 3 4 5 6 7 8
| lsof -u mysql -i
lsof -i :3306
lsof -p $(pgrep mysqld) | wc -l
|
场景 5:查找已删除但仍在占用的文件
某些进程还在使用已被删除的文件,导致磁盘空间未释放:
1 2 3 4 5 6 7 8 9
| lsof | grep '(deleted)'
lsof -nP | grep '(deleted)' | awk '{print $2, $1, $NF}'
kill -HUP $(lsof -t /var/log/nginx/access.log)
|
场景 6:排查文件描述符泄漏
长时间运行的服务可能出现文件描述符泄漏:
1 2 3 4 5 6 7 8 9 10
| while true; do count=$(lsof -p 1234 | wc -l) echo "$(date) - FD count: $count" sleep 10 done
cat /proc/1234/limits | grep "open files"
|
场景 7:配合其他命令组合使用
1 2 3 4 5 6 7 8
| lsof -i :80 -c nginx
lsof -nP -i TCP -s TCP:LISTEN | awk 'NR>1 {print $1, $2, $9}'
lsof | awk 'NR>1 {count[$3]++} END {for(u in count) print u, count[u]}' | sort -k2 -rn | head -10
|
进阶技巧
1. 重复执行模式
类似 watch 命令,内置周期刷新:
1 2 3 4 5
| lsof -r 3 -i :80
lsof -r 5 -c nginx
|
2. 脚本化输出(-t 和 -F)
1 2 3 4 5 6
| kill -9 $(lsof -t -i :8080)
lsof -F pcfn -i :443
|
3. 查看 Unix 域套接字
4. 查看所有 NFS 文件
5. 查看当前工作目录(cwd)
性能与安全注意事项
权限问题:普通用户只能查看自己的进程,root 可以查看所有进程。如果需要让普通用户执行完整 lsof,需要设置 SUID 或使用 sudo。
性能影响:在高并发服务器上执行无参数的 lsof 可能会产生较大 I/O 开销,建议总是带上过滤条件。
加速查询:
安全限制:某些系统上 /proc 的访问权限可能受 hidepid 挂载选项限制。
常见问题排查
| 问题 | 原因 | 解决方法 |
lsof: no permission | 权限不足 | 使用 sudo |
| 输出为空 | 没有匹配项 | 确认端口/进程号是否正确 |
| 响应缓慢 | DNS 反向解析 | 加 -n 选项 |
| 端口被占用但 lsof 找不到 | 可能是其他用户或 root 进程 | 使用 sudo 重试 |
FD 类型显示为 DEL | 文件已被删除但仍被打开 | 重启相关进程 |
lsof: WARNING: /proc filesystem ... | /proc 未挂载或不可读 | 检查 mount | grep proc |
命令速查表
| 需求 | 命令 |
| 查看端口占用 | lsof -i :端口号 |
| 查看某个进程的文件 | lsof -p PID |
| 查看某个用户的文件 | lsof -u 用户名 |
| 查看某个命令打开的文件 | lsof -c 命令名 |
| 查看所有监听端口 | lsof -nP -i TCP -s TCP:LISTEN |
| 查看已建立连接 | lsof -i TCP -s TCP:ESTABLISHED |
| 查看目录下打开的文件 | lsof +D /目录路径 |
| 查看已删除文件的进程 | lsof -nP | grep '(deleted)' |
| 仅输出 PID | lsof -t -i :端口 |
| 持续监控 | lsof -r 秒数 -i :端口 |
总结
lsof 是一个功能极其强大的诊断工具,掌握了它,就等于拥有了一把打开 Linux 系统”黑盒”的钥匙。无论是排查端口冲突、定位磁盘空间未释放、诊断网络连接问题,还是分析进程文件描述符泄漏,lsof 都能快速给出答案。结合 -n、-P、-t 等选项灵活组合使用,可以让日常运维工作事半功倍。
本文由AI辅助生成,内容仅供参考