lsof 命令详解
更新时间:2026-08-28。本文是「一个命令一个文档」系列,聚焦
lsof(list open files,列出打开的文件)——进程与系统命令族(见进程与系统命令族)。在 Linux 里"一切皆文件",连网络连接也是"打开的文件"。
lsof 列出系统当前所有被进程打开的文件。这里的"文件"是广义的:普通文件、目录、管道、设备,以及网络套接字(socket,进程间网络通信的端点)。所以 lsof 既能查"谁占用了这个文件",也能查"哪个进程占了 8080 端口"。
一、查端口被谁占用
lsof -i :8080 # 看谁在监听/使用 8080 端口
lsof -i :80 -sTCP:LISTEN # 只看处于 LISTEN 的(已监听)
lsof -i tcp # 所有 TCP 连接
lsof -i @192.168.1.10 # 看连到某 IP 的"Address already in use" 起不来服务?
lsof -i :端口直接告诉你哪个进程(PID/COMMAND)占着。-sTCP:LISTEN能过滤出真正在监听的,排除掉已建立的普通连接。这是端口冲突排查的第一命令,替代已被弃用的netstat(见 ss)。
二、查某进程打开了什么
lsof -p 1234 # 进程 1234 打开的所有文件/连接
lsof -p 1234 -i # 只看它的网络连接
lsof -c nginx # 命令名以 nginx 开头的进程
lsof -u www-data # 某用户打开的文件排查"进程怎么读了不该读的文件""为什么删不掉目录(被某进程 hold 住)"时,
lsof -p列出该进程所有打开的 fd(文件描述符)。尤其是"文件删了但磁盘空间不释放"——往往是进程还开着那个已删除文件的句柄,重启进程或lsof | grep deleted能定位。
三、恢复误删但仍被打开的文件
lsof | grep deleted # 找已删除但还被进程占用的文件
# 假设 PID 1234 的 fd 5 指向 /var/log/app.log (deleted)
cp /proc/1234/fd/5 /var/log/app.log.rescuedLinux 删除文件只是 unlink 目录项,只要还有进程开着它的 fd,数据仍在磁盘上。通过
/proc/<pid>/fd/<n>能把内容 copy 回来——这是救急误删日志的硬核手段。当然,正道是立刻让进程重新打开/滚动日志,而不是依赖这招。
四、常见组合与选项
| 选项 | 作用 |
|---|---|
-i | 网络相关(端口/IP/协议) |
-p | 指定 PID |
-c | 指定命令名前缀 |
-u | 指定用户 |
-n | 不解析主机名(更快) |
-P | 端口用数字不解析服务名 |
+D /path | 查某目录下被打开的文件 |
-n -P能显著加快 lsof(避免 DNS 和端口名解析卡顿),查端口时习惯带上:lsof -nP -i :8080。+D递归查目录下哪些文件正被打开,定位"为什么 umount 不掉"(有文件被占用)。
五、和 fuser / ss 的关系
| 工具 | 专长 |
|---|---|
lsof | 通用:文件+网络+进程全景 |
| fuser | 反查"哪个进程占了某文件/端口"(更轻) |
| ss | 专看 socket 统计,比 netstat 快(见 ss) |
想看"端口谁占"
lsof -i和ss -lpt都能办,ss 更快更专;想看"进程开了哪些文件"用lsof -p;想看"某文件被谁占"用 fuser 或lsof +D。按需求挑最顺手的。
六、实战:端口冲突 / 磁盘不释放
# 端口被占
lsof -nP -i :8080 # 找到 PID,kill 或换端口
# 删了大文件但 df 没释放
lsof +L1 | grep deleted # 找 hold 住已删文件的进程,重启它释放第一条解决"起服务报端口占用",第二条解决经典的"日志删了 df -h 空间却没回来"——+L1 列出链接数掉到 0(已删)但仍打开的文件,重启对应进程即可真正释放磁盘。
一句话总结
lsof = 列出打开的文件(含 socket/管道):-i :端口 查端口占用(替代 netstat)、-p 看进程开了啥、-c/-u 按命令/用户过滤、-nP 加速、+D 查目录占用;还能借 /proc/<pid>/fd 救回误删仍打开的文件、+L1 找删了却没释放磁盘的进程。端口冲突与"删了不释放空间"排查首选。