#!/bin/bash # 查找随机空闲端口 # 用途: # 在指定端口范围内,随机选择一个当前未被监听(TCP/UDP)的端口 # 参数: # $1: 起始端口(默认 10001) # $2: 结束端口(默认 65535) # $3: 最大随机尝试次数(默认 100) find_free_port() { local start="${1:-10001}" local max="${2:-65535}" local attempts="${3:-100}" # ------------------------------------------------------------ # 收集当前正在监听的端口(TCP + UDP) # 优先使用 ss,其次 netstat # ------------------------------------------------------------ local used_ports raw if command -v ss >/dev/null 2>&1; then # ss 输出示例: # LISTEN 0 128 0.0.0.0:22 raw=$(ss -lntu 2>/dev/null || true) used_ports=$(printf "%s\n" "$raw" \ | awk '{print $5}' \ | sed -E 's/.*[:]//g') elif command -v netstat >/dev/null 2>&1; then # netstat 输出示例: # tcp 0 0 0.0.0.0:22 raw=$(netstat -lntu 2>/dev/null || true) used_ports=$(printf "%s\n" "$raw" \ | awk '{print $4}' \ | sed -E 's/.*[:]//g') else echo "Error: ss or netstat is required to check listening ports." >&2 return 2 fi # ------------------------------------------------------------ # 将已占用端口存入关联数组,便于 O(1) 判断 # 需要 bash 4+ # ------------------------------------------------------------ declare -A used_map local p for p in $used_ports; do # 过滤非数字字段(如 *、:::) if [[ $p =~ ^[0-9]+$ ]]; then used_map["$p"]=1 fi done # ------------------------------------------------------------ # 随机尝试若干次 # 每次随机生成一个端口,只要未被监听就立即返回 # ------------------------------------------------------------ local port i for ((i=0; i&2 return 1 } change_port(){ local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" local config_dir=$(readlink -f "$script_dir/../config") local config_file="$config_dir/config.json" local port=$(find_free_port) modify_json_file "$config_file" ".listen" ":$port" echo "已分配新的空闲端口, 设置端口成功" }