侧边栏壁纸
博主头像
Ivan Zhang

所谓更牛,就是换个罪受

  • 累计撰写 48 篇文章
  • 累计创建 54 个标签
  • 累计收到 6 条评论

目 录CONTENT

文章目录

跨系统端口进程终止方案文档

Ivan Zhang
2025-02-25 / 0 评论 / 0 点赞 / 126 阅读 / 3,378 字
温馨提示:
本文最后更新于 ,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
有什么问题或观点欢迎评论留言,或者 交流。
如果觉得文章对您有所帮助,可以给博主打赏鼓励一下。

在使用 IntelliJ IDEA 等工具做 Java 开发时,偶尔会遇到 IDEA 中已经停止应用实例,但是重启启动的时候提示端口已经被占用。虽然可以改个端口启动,或者手动找到对应进程干掉,但是总是麻烦又恼人,因此撸一个脚本用来快速处理该场景问题。

以下为 Windows、macOS、Linux 三个系统通过端口号获取 PID 并终止进程的完整解决方案文档,综合了多平台特性与安全性设计:

一、Windows 系统

实现脚本

@echo off
chcp 65001 >nul  && cls
REM 确保控制台使用 UTF-8 编码(需配合支持 Unicode 的字体,如 "Lucida Console")
setlocal enabledelayedexpansion

REM 脚本功能:终止占用指定端口的进程(支持多端口,无参数时使用默认端口列表)
REM 默认端口:8080 9001
REM 使用示例:kill_ports.bat 8080 9001

REM 自动请求管理员权限(可选)
NET FILE >nul 2>&1
if %errorlevel% neq 0 (
    echo 正在请求管理员权限...
    powershell Start-Process "%~0" %* -Verb RunAs
    exit /b
)

REM 设置默认端口列表
set "default_ports=8080 9001"
set "ports=%*"

REM 如果入参为空,使用默认端口
if "!ports!"=="" (
    set "ports=!default_ports!"
    echo 未提供端口参数,使用默认列表:!ports!
)

REM 遍历所有端口(用户输入或默认)
for %%p in (!ports!) do (
    set "port=%%p"
    echo 正在检查端口: !port! ...

    REM 查找占用端口的 PID
    set "pid_list="
    for /f "tokens=5" %%a in ('netstat -ano ^| findstr ":!port! " ^| findstr "LISTENING"') do (
        set "pid=%%a"
        set "pid_list=!pid_list! !pid!"
    )

    REM 终止进程
    if defined pid_list (
        echo 发现进程 PID: !pid_list!
        for %%i in (!pid_list!) do (
            taskkill /F /PID %%i >nul 2>&1
            if !errorlevel! equ 0 (
                echo [成功] 端口 !port! 的进程 PID:%%i 已终止
            ) else (
                echo [失败] 端口 !port! 的进程 PID:%%i 终止失败(可能需要管理员权限)
            )
        )
    ) else (
        echo 未找到占用端口 !port! 的进程
    )
    echo -------------------------------
)

endlocal
pause

特性说明

  1. 自动提权:通过 PowerShell 请求管理员权限,避免权限不足问题
  2. 多端口支持:支持命令行参数输入或默认端口列表(8080,9001)
  3. 精准匹配:使用 netstat 过滤 LISTENING 状态的端口进程
  4. 结果反馈:明确标注终止成功/失败状态,提示权限问题

二、macOS 系统

实现脚本

#!/bin/zsh

# 默认端口列表
default_ports=(8080 9001)
ports=(${@:-${default_ports[@]}})

# 权限检查
if [[ $EUID -ne 0 ]]; then
    echo "检测到非 root 权限,部分进程可能需要 sudo 执行"
fi

# 遍历端口终止进程
for port in ${ports[@]}; do
    echo "检查端口: $port"
    pids=$(lsof -ti :$port | tr '\n' ' ')

    if [[ -n "$pids" ]]; then
        echo "发现进程 PID: $pids"
        for pid in ${pids[@]}; do
            kill -9 $pid 2>/dev/null
            if [[ $? -eq 0 ]]; then
                echo "[成功] 端口 $port 进程 PID:$pid 已终止"
            else
                echo "[失败] 端口 $port 进程 PID:$pid 终止失败(尝试 sudo 执行)"
            fi
        done
    else
        echo "端口 $port 无进程占用"
    fi
    echo "------------------------------"
done

特性说明

  1. 动态参数处理:支持命令行输入或默认端口列表
  2. 权限检测:提示非 root 用户可能存在的权限限制
  3. 精确查找:通过 lsof -ti 获取精确 PID 列表
  4. 批量处理:支持同一端口多个进程的终止操作
  5. 错误隔离:独立处理每个 PID 的终止结果

三、Linux 系统

实现脚本

#!/bin/bash

# 默认端口列表
default_ports=(8080 9001)
ports=("${@:-${default_ports[@]}}")

# 权限检查
if [[ $EUID -ne 0 ]]; then
    echo "提示:部分进程可能需要 sudo 权限终止"
fi

# 遍历端口终止进程
for port in "${ports[@]}"; do
    echo "检查端口: $port"
    pids=$(ss -ltnpu | awk -v port=":$port$" '$5 ~ port {split($6,a,"=");print a[2]}' | uniq)

    # 备用方案(若 ss 不可用)
    [[ -z "$pids" ]] && pids=$(lsof -ti :$port)

    if [[ -n "$pids" ]]; then
        echo "发现进程 PID: $pids"
        for pid in ${pids}; do
            kill -9 $pid 2>/dev/null
            if [[ $? -eq 0 ]]; then
                echo "[成功] 端口 $port 进程 PID:$pid 已终止"
            else
                sudo kill -9 $pid 2>/dev/null
                [[ $? -eq 0 ]] && echo "[sudo 成功] 端口 $port 进程终止" || echo "[致命错误] 进程 $pid 终止失败"
            fi
        done
    else
        echo "端口 $port 无进程占用"
    fi
    echo "------------------------------"
done

特性说明

  1. 双引擎检测:优先使用 ss 命令获取进程信息,兼容性更强
  2. 自动降级:当 ss 不可用时回退到 lsof 方案
  3. 智能提权:普通用户首次尝试失败后自动使用 sudo 重试
  4. 进程关联:通过 ss 提取的 PID 包含套接字关联进程
  5. 错误分级:区分普通错误与需管理员干预的致命错误

四、跨平台共性设计

  1. 默认端口机制:均支持 8080 和 9001 默认端口
  2. 输入扩展性:支持通过命令行参数指定任意端口
  3. 状态反馈:统一采用分级状态标识(成功/失败/警告)
  4. 日志友好:使用分隔符 ------------------------------ 增强可读性
  5. 错误抑制2>/dev/null 抑制非必要系统报错

五、使用示例

# Windows
kill_ports.bat 3000 8081

# macOS/Linux
chmod +x kill_ports.sh
./kill_ports.sh 3000 8081

参考来源:

0

评论区