最准方法是sudo lsof -n -p -p pid,加-n避免dns延迟、-p显示数字端口、sudo确保权限;type为ipv4/ipv6即端口,reg/dir为文件,name列显示具体路径或*:端口。

直接结论:用 lsof -p PID 最准,但必须加 -n 和 -P,否则容易看错端口或卡住。
查指定进程打开的端口和文件:lsof -p PID 是核心命令
它会列出该进程所有打开的文件描述符,包括网络 socket、日志文件、配置文件、共享库等。输出里 TYPE 列为 IPv4 或 IPv6 的行就是端口;REG 或 DIR 的行是普通文件或目录。
常见错误现象:
- 不加
-n:IP 反向解析超时,命令卡住几秒甚至更久 - 不加
-P:端口显示成http、https,看不出实际用了 80 还是 8080 - 没加
sudo:看不到其他用户启动的进程(比如 root 启的 nginx),只看到当前用户的部分 FD
正确写法示例:
sudo lsof -n -P -p 1234
其中 1234 替换为你想查的 PID。重点关注 FD(如 3u)、TYPE(IPv4 表示端口)、NAME(如 *:8080 或 /var/log/app.log)这几列。
lsof -c process_name 查所有同名进程的资源
适合你只知道服务名(比如 java、node、nginx),但不确定 PID 的场景。它会匹配所有 COMMAND 字段以该字符串开头的进程。
注意点:
-
-c java会匹配java、javaw、java-app,不是精确全匹配 - 如果进程名含空格(如
python3 myserver.py),COMMAND列只显示python3,得用lsof -p $(pgrep -f "myserver.py")辅助 - 同样要加
-n -P,否则输出混乱或延迟
示例:
sudo lsof -n -P -c nginx
快速定位监听端口对应的进程:lsof -i :PORT
这不是查“某个进程”,而是反向查“哪个进程占了这个端口”。常用于服务启动失败报 Address already in use 时。
关键参数组合:
-
-i :8080:只查 8080 端口(TCP/UDP 都包含) -
-iTCP:8080:只查 TCP 的 8080(排除 UDP 干扰) -
-i@127.0.0.1:8080:限定绑定地址,避免查到*:8080这种通配监听
典型错误:
- 漏掉
sudo:看不到非当前用户进程,返回空结果,误以为端口空闲 - 没加
-P:看到:http却不知道是不是 80 端口 - 用
lsof -i :8080 | grep LISTEN多余——lsof -i :8080本身就能看出状态,NAME列末尾就是(LISTEN)或(ESTABLISHED)
查被删除但仍在占用磁盘的文件:lsof | grep deleted
这类文件在 NAME 列会显示类似 /var/log/app.log (deleted)。虽然文件路径已删,但进程仍持有 fd,空间不会释放。
使用场景:
- df 显示磁盘满,但
du -sh /var/log总和远小于总量 - logrotate 执行后空间没释放
操作建议:
- 先确认是哪个进程:
lsof | grep deleted | head -10 - 重启对应服务是最稳妥解法;若不能重启,可用
kill -HUP PID尝试让其重新打开日志(取决于程序是否支持) - 不要直接
echo > /proc/PID/fd/N清空——可能破坏进程行为,且下次写入仍会增长
真正容易被忽略的是:lsof 输出中 FD 列为 txt 的行,代表该进程正在执行的二进制文件本身。如果这个文件被删了(比如升级时覆盖),lsof 也会标 (deleted),但进程还能继续跑——这种 case 很隐蔽,lsof | grep txt.*deleted 才能抓出来。











