在开发与运维过程中,端口冲突问题常常令人头疼。今天给大家分享一个超实用的 shell 脚本,专门用来清理占用 8080 端口的程序。通过这个脚本,能够迅速定位并关闭那些占用关键端口的进程,极大提升开发与运维效率,减少因端口冲突导致的各种麻烦。无论是开发人员在本地环境测试,还是运维人员管理服务器,它都能派上大用场,赶紧收藏试试吧!
用法
sh clean_port.sh 没有端口参数,默认8080
sh clean_port.sh 8090
#!/bin/bash
# 设置默认端口
PORT=8080
# 检查是否有参数传入
if [ $# -gt 0 ]; then
# 检查参数是否为数字 (使用 POSIX 兼容语法)
if [ -n "$(echo $1 | grep -E '^[0-9]+$')" ]; then
PORT=$1
else
echo "错误: 端口必须是数字"
exit 1
fi
fi
# 输出标题
echo "===== 端口清理工具 ====="
echo "正在使用多种方法查找占用 $PORT 端口的进程..."
# 方法1: 使用 lsof
echo "方法1: 使用 lsof 查找..."
PORT_PIDS_LSOF=$(lsof -i :$PORT -t 2>/dev/null)
# 方法2: 使用 netstat
echo "方法2: 使用 netstat 查找..."
PORT_PIDS_NETSTAT=$(netstat -tulpn 2>/dev/null | grep ":$PORT " | awk '{print $7}' | cut -d'/' -f1 | grep -v "^$")
# 方法3: 使用 ss
echo "方法3: 使用 ss 查找..."
PORT_PIDS_SS=$(ss -tulpn 2>/dev/null | grep ":$PORT " | awk '{print $7}' | cut -d',' -f2 | cut -d'=' -f2 | grep -v "^$")
# 合并所有找到的 PID 并去重
ALL_PIDS=$(echo "$PORT_PIDS_LSOF $PORT_PIDS_NETSTAT $PORT_PIDS_SS" | tr ' ' '\n' | sort -u | grep -v "^$")
if [ -z "$ALL_PIDS" ]; then
echo "没有找到占用 $PORT 端口的进程。"
else
echo "找到以下进程占用 $PORT 端口:"
for PID in $ALL_PIDS; do
# 获取进程信息
PROCESS_INFO=$(ps -p $PID -o pid,user,command 2>/dev/null | tail -n 1)
if [ ! -z "$PROCESS_INFO" ]; then
echo "$PROCESS_INFO"
fi
done
echo "正在终止这些进程..."
for PID in $ALL_PIDS; do
if ps -p $PID > /dev/null 2>&1; then
echo "终止进程 $PID..."
# 先尝试正常终止
kill $PID 2>/dev/null
sleep 2
# 检查进程是否还存在
if ps -p $PID > /dev/null 2>&1; then
echo "进程 $PID 没有响应,正在强制终止..."
kill -9 $PID 2>/dev/null
sleep 1
fi
fi
done
fi
# 同时清理可能的 Go 运行进程
echo "正在清理 Go 运行进程..."
GO_PIDS=$(pgrep -f "go run main.go" 2>/dev/null)
if [ -z "$GO_PIDS" ]; then
echo "没有找到正在运行的 Go 进程。"
else
echo "找到以下 Go 进程:"
for PID in $GO_PIDS; do
PROCESS_INFO=$(ps -p $PID -o pid,user,command | tail -n 1)
echo "$PROCESS_INFO"
done
echo "正在终止这些进程..."
for PID in $GO_PIDS; do
kill $PID 2>/dev/null
sleep 2
if ps -p $PID > /dev/null 2>&1; then
echo "进程 $PID 没有响应,正在强制终止..."
kill -9 $PID 2>/dev/null
sleep 1
fi
done
fi
# 等待端口完全释放
echo "等待端口完全释放..."
sleep 5
# 最终检查端口是否已释放
PORT_IN_USE=$(netstat -tulpn 2>/dev/null | grep ":$PORT " || ss -tulpn 2>/dev/null | grep ":$PORT " || lsof -i :$PORT 2>/dev/null)
if [ -z "$PORT_IN_USE" ]; then
echo "端口 $PORT 已成功释放!"
else
echo "警告:端口 $PORT 仍被占用。尝试更强力的方法..."
# 尝试使用 fuser 命令强制释放端口
if command -v fuser > /dev/null 2>&1; then
echo "使用 fuser 命令强制释放端口..."
fuser -k ${PORT}/tcp 2>/dev/null
sleep 3
fi
# 再次检查
PORT_STILL_IN_USE=$(netstat -tulpn 2>/dev/null | grep ":$PORT " || ss -tulpn 2>/dev/null | grep ":$PORT " || lsof -i :$PORT 2>/dev/null)
if [ -z "$PORT_STILL_IN_USE" ]; then
echo "端口 $PORT 已成功释放!"
else
echo "警告:无法释放端口 $PORT。建议尝试以下操作:"
echo "1. 重启终端"
echo "2. 等待几分钟后再试"
echo "3. 尝试使用不同的端口"
fi
fi
echo "清理完成!"
echo "现在可以重新启动您的应用了。"