4.3.4 打开文件与端口检查(lsof、ss)

打开文件与端口检查(lsof、ss)#

在进程诊断中,定位“进程打开了哪些文件/端口、端口被谁占用、连接状态如何”是高频需求。本节聚焦 lsof(文件/端口占用)与 ss(套接字/连接统计),并提供可执行示例、排错与练习。

原理草图:从进程到文件/端口#

文章图片

安装与版本确认#

  • 安装
# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y lsof iproute2

# RHEL/CentOS/AlmaLinux
sudo yum install -y lsof iproute
  • 确认版本
lsof -v | head -n 1
ss -V

lsof:打开文件与端口占用(含解释与示例)#

  • 常见场景:端口占用、文件被占用导致无法删除、进程打开配置/日志。
  • 常用参数解释
  • -i 网络文件(IP/端口)
  • -p 指定 PID
  • -u 指定用户
  • -nP 禁用 DNS/端口解析(更快)
  • -sTCP:LISTEN 仅查看监听
  • 示例 1:查看 80 端口占用
sudo lsof -nP -i :80

预期输出(示例):

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   1234 root    6u  IPv4  20123      0t0  TCP *:80 (LISTEN)

解释:FD 6u 表示读写,NAME 显示监听端口。

  • 示例 2:查看 MySQL 监听
sudo lsof -nP -iTCP:3306 -sTCP:LISTEN

解释:过滤 TCP 3306 且处于 LISTEN 状态。

  • 示例 3:查看某进程打开的所有文件
sudo lsof -p 1234

解释:列出 PID=1234 所有打开的文件、套接字与管道。

  • 示例 4:找出占用某文件的进程
sudo lsof /var/log/nginx/access.log

解释:用于排查“文件被占用导致无法删除/移动”。

ss:套接字与连接状态(含解释与示例)#

  • 常用参数解释
  • -l 只显示监听
  • -n 禁用解析(数值显示)
  • -t TCP
  • -u UDP
  • -p 显示进程信息
  • -s 汇总统计
  • 示例 1:查看监听端口
sudo ss -lntp

预期输出(示例):

State  Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0      128    0.0.0.0:80        0.0.0.0:*     users:(("nginx",pid=1234,fd=6))

解释:Recv-Q/Send-Q 为队列长度,Process 显示进程与 FD。

  • 示例 2:查看所有 TCP 连接
sudo ss -antp

解释:含 ESTAB/TIME-WAIT 等状态与进程。

  • 示例 3:统计连接状态
ss -s

解释:快速判断连接是否异常激增。

  • 示例 4:过滤某端口连接
sudo ss -antp '( sport = :80 )'

解释:只看本地源端口为 80 的连接。

综合示例:定位端口占用并确认文件关联#

# 1) 找出 8080 端口占用进程
sudo ss -lntp | grep ':8080'

# 2) 假设 PID=5678,查看该进程打开文件
sudo lsof -p 5678 | head -n 10

# 3) 若需要确认配置文件是否被打开
sudo lsof -p 5678 | grep nginx.conf

预期效果:确认监听进程与其打开的配置/日志文件。

排错与常见问题#

  • 看不到进程信息(Process 为空)
  • 原因:权限不足
  • 处理:
sudo ss -lntp
sudo lsof -nP -i :80
  • lsof 执行缓慢
  • 原因:解析 DNS/服务名
  • 处理:
sudo lsof -nP -i :80
  • 端口显示被占用但服务已停止
  • 原因:进程残留或 TIME-WAIT 连接
  • 处理:
sudo ss -antp | grep ':80'
ps -fp <PID>

练习#

  1. 启动一个临时 HTTP 服务并检查端口占用:
# 启动临时服务
python3 -m http.server 8000 >/tmp/http.log 2>&1 & echo $! > /tmp/http.pid

# 查看端口占用
sudo ss -lntp | grep ':8000'

# 查看进程打开的文件
sudo lsof -p $(cat /tmp/http.pid) | head -n 5
  1. 模拟文件被占用无法删除:
# 打开文件并保持占用
tail -f /var/log/syslog >/tmp/tail.log 2>&1 & echo $! > /tmp/tail.pid

# 尝试定位占用
sudo lsof /var/log/syslog

# 结束占用进程
kill $(cat /tmp/tail.pid)