xray_docker/bin/update_port.sh
2026-01-15 13:38:07 +08:00

85 lines
2.7 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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<attempts; i++)); do
# 在 [start, max] 范围内生成随机端口
port=$(( RANDOM % (max - start + 1) + start ))
# 如果端口不在已监听表中,则认为可用
if [[ -z "${used_map[$port]}" ]]; then
echo "$port"
return 0
fi
done
# ------------------------------------------------------------
# 多次随机尝试后仍未找到可用端口
# 通常意味着端口范围过小或已被大量占用
# ------------------------------------------------------------
echo "Error: no free port found after $attempts random attempts." >&2
return 1
}
update_port(){
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹路径
local config_file="$script_dir/../conf/config.json"
local port=$(find_free_port)
modify_json_file "$config_file" ".inbounds[0].port" "$port"
echo "设置端口成功"
}