lsof 是 Linux/Unix 系统中一个非常强大的命令,全称是 List Open Files(列出打开的文件)。在 Linux 中,“一切皆文件”,所以 lsof 不仅可以查看普通文件,还可以查看网络连接(socket)、设备文件、目录、管道等。
以下是 lsof 命令的详细讲解,涵盖其原理、常用参数、输出解读以及实战案例。
1. 核心原理
当进程打开一个文件时,内核会在内存中维护该进程的打开文件列表。lsof 命令通过读取内核中的 vnode 和 file 结构信息,将这些数据提取并格式化输出。
权限问题:
普通用户执行 lsof 只能看到自己启动的进程。
root 用户或使用 sudo 可以看到所有进程。
2. 基本语法
lsof [选项] [文件名|PID|用户名]如果不加任何参数,lsof 会列出当前系统所有打开的文件(数据量巨大,通常配合管道或过滤条件使用)。
3. 常用选项详解
(1) 按条件筛选
(2) 组合与逻辑
默认是 OR 关系:lsof -u root -i :80 表示列出 root 用户 或 端口 80 的连接。
使用 -a 表示 AND 关系:lsof -u root -a -i :80 表示列出 root 用户 并且 端口 80 的连接。
4. 输出字段解读
执行 lsof 后,通常会看到以下列:
5. 实战案例
案例 1:查找占用某个端口的进程(排查端口冲突)
# 查看谁占用了 8080 端口
lsof -i :8080
# 结合 -t 只输出 PID,配合 kill 使用
kill -9 $(lsof -t -i :8080)案例 2:查看某个进程打开的所有文件
# 先找到进程名或 PID
lsof -p 1234案例 3:恢复被删除但仍占用的文件(磁盘空间未释放)
有时删除了一个大日志文件,但磁盘空间没释放,原因是进程还在写该文件。
# 1. 查找状态为 deleted 的文件
lsof | grep deleted
# 2. 根据显示的 PID 和 FD,清空文件(无需重启进程)
# 假设 PID 为 1234,FD 为 3w
cat /dev/null > /proc/1234/fd/3案例 4:查看特定目录下正在被使用的文件
# 查看 /var/log 下哪些文件正在被写入
lsof +D /var/log案例 5:查看网络连接状态(类似 netstat)
# 查看所有监听状态的 TCP 连接
lsof -i tcp -s tcp:LISTEN
# 查看所有已建立的连接
lsof -i tcp -s tcp:ESTABLISHED案例 6:查看某个用户的活动
# 查看用户 www-data 打开的所有文件及网络连接
lsof -u www-data
# 排除 root 用户,查看普通用户
lsof -u ^root6. 高级技巧
(1) 周期性监控
结合 watch 命令实时刷新:
watch -n 1 'lsof -i :80'(2) 查找正在使用某个动态库(.so)的进程
当你想替换一个 .so 文件但提示“文件正忙”时:
lsof /usr/lib/libssl.so.1.1(3) 列出所有打开的 Unix 域套接字
lsof -U(4) 查看进程当前工作目录
lsof -p PID | grep cwd
# 或使用 pwdx 命令(更简单)
pwdx PID7. 注意事项与性能
性能开销:在高负载服务器上运行 lsof(特别是无参数或大范围搜索)可能会消耗较多 CPU 和内存,因为需要遍历 /proc 文件系统。
内核限制:如果系统打开的文件句柄非常多(cat /proc/sys/fs/file-nr),lsof 执行时间可能会较长。
输出截断:COMMAND 列默认只显示前 9 个字符,如果进程名太长会截断。可以使用 -c 配合正则精确匹配。
总结
lsof 是 Linux 运维和开发中的必备工具。它的强大之处在于能够将“进程”与“资源(文件、端口、设备)”关联起来。无论是排查端口冲突、磁盘空间未释放、还是追踪进程行为,lsof 都是第一选择。