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禁用解析(数值显示)-tTCP-uUDP-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>
练习#
- 启动一个临时 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
- 模拟文件被占用无法删除:
# 打开文件并保持占用
tail -f /var/log/syslog >/tmp/tail.log 2>&1 & echo $! > /tmp/tail.pid
# 尝试定位占用
sudo lsof /var/log/syslog
# 结束占用进程
kill $(cat /tmp/tail.pid)