📢 开发必备!一键清理 8080 端口冲突,这个 Shell 脚本让服务部署快人一步!🔥

124 阅读2分钟

在开发与运维过程中,端口冲突问题常常令人头疼。今天给大家分享一个超实用的 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 "现在可以重新启动您的应用了。"