Linux如何查看进程打开的文件-Linux系统中lsof命令的高级使用技巧解析

作者:袖梨 2026-06-02

在Linux系统中,lsof命令是排查进程文件占用的利器,掌握基础参数组合就能应对大多数场景。本文详解四种典型应用场景,助你精准定位文件占用问题。

直接用 lsof 查进程打开的文件,绝大多数情况不需要"高级用法"——基础选项组合就能解决 95% 的问题。所谓"高级",其实是把几个常用参数串起来应对具体场景,而不是堆砌冷门开关。

查某个进程打开了哪些文件(按 PID)

最常见需求:知道一个进程卡住了、占着磁盘或端口,想看它到底在读写什么。

  1. lsof -p 1234 是起点,但默认输出太长,建议加 -n(不解析主机名/端口名)和 -P(不查服务名),避免卡顿或 DNS 查询延迟
  2. 如果只关心普通文件(非 socket、非设备),可过滤 TYPE:lsof -p 1234 -a -d ^cwd,^txt,^mem -a -t 中的 -d ^cwd,^txt,^mem 排除当前目录、代码段、内存映射,剩下多为实际读写的文件
  3. 注意:-p 必须用 root 权限才能看到其他用户的进程;普通用户执行时,lsof -p $PID 只能查自己启动的进程

查谁在用某个端口(TCP/UDP)

端口被占用、服务起不来、连接连不上?lsof -i 是第一响应工具,但写法有坑。

  1. lsof -i :8080 能查到或连接 8080 的所有进程,但默认会解析域名和端口名(比如把 80 显示成 http),加 -n -P 更快更准
  2. 只想看 TCP 或 UDP?用 lsof -i tcp:3306lsof -i udp:53,不要写成 lsof -i tcp -i :3306 —— 这样是 AND 逻辑,但 -i tcp 本身不含端口条件,结果可能为空
  3. IPv4 和 IPv6 分开查更稳妥:lsof -i4 :22lsof -i :22 更明确,避免因双栈配置导致漏掉在 :::22 的 sshd

查某个目录下被哪些进程占用(umount 失败时必用)

卸载失败报 device is busy,本质是进程 cwd、root、或打开了该目录下的文件。不能只靠 lsof /path

  1. lsof +D /var/log 递归扫描整个目录树,速度慢、权限要求高(需能遍历子目录),且容易因权限不足中断
  2. 更实用的是 lsof +d /var/log(非递归),只扫一级目录下的打开文件,配合 grep 快速定位:lsof +d /var/log | grep REG
  3. 别忽略 cwdrtd 类型:进程当前工作目录是 /var/log,哪怕没打开任何文件,也会阻止 umount —— 这类条目在 lsof +d /var/log 输出里 FD 列显示为 cwd,不是 REG

查被删除但仍被占用的文件(磁盘空间不释放)

日志轮转后 df 显示磁盘满,但 du -sh /var/log 却不大?大概率是文件被删了,但进程还拿着 fd。

  1. lsof | grep deleted 是标准做法,但输出中 NAME 列会显示类似 /var/log/nginx/access.log (deleted)
  2. 注意:这个命令必须用 root 执行,否则看不到其他用户的 deleted 文件;普通用户执行时,只会显示自己进程持有的 deleted 文件
  3. 找到 PID 后,可选操作是重启对应服务(如 systemctl restart nginx),而非直接 kill —— 强杀可能引发服务异常;若无法重启,lsof -p PID 再确认是否只有这一个 deleted 文件在占空间

通过以上四个典型场景的分析可见,lsof命令的关键在于参数组合与权限控制。合理运用基础参数组合,配合root权限使用,能有效解决绝大多数文件占用问题,无需过度依赖复杂参数。

相关文章

精彩推荐