mirror of
https://github.com/wnlen/clash-for-linux.git
synced 2026-02-04 10:11:28 +08:00
Add clashctl and auto port selection
This commit is contained in:
102
scripts/port_utils.sh
Normal file
102
scripts/port_utils.sh
Normal file
@ -0,0 +1,102 @@
|
||||
#!/bin/bash
|
||||
|
||||
PORT_CHECK_WARNED=${PORT_CHECK_WARNED:-0}
|
||||
|
||||
is_port_in_use() {
|
||||
local port="$1"
|
||||
if command -v ss >/dev/null 2>&1; then
|
||||
ss -lnt | awk '{print $4}' | grep -E "(:|\.)${port}$" >/dev/null 2>&1
|
||||
return $?
|
||||
fi
|
||||
if command -v netstat >/dev/null 2>&1; then
|
||||
netstat -lnt | awk '{print $4}' | grep -E "(:|\.)${port}$" >/dev/null 2>&1
|
||||
return $?
|
||||
fi
|
||||
if command -v lsof >/dev/null 2>&1; then
|
||||
lsof -iTCP -sTCP:LISTEN -P -n | awk '{print $9}' | grep -E "(:|\.)${port}$" >/dev/null 2>&1
|
||||
return $?
|
||||
fi
|
||||
if [ "$PORT_CHECK_WARNED" -eq 0 ]; then
|
||||
echo -e "\033[33m[WARN] 未找到端口检测工具,端口冲突检测可能不准确\033[0m" >&2
|
||||
PORT_CHECK_WARNED=1
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
find_available_port() {
|
||||
local start_port=${1:-20000}
|
||||
local end_port=${2:-65000}
|
||||
local port
|
||||
|
||||
if command -v shuf >/dev/null 2>&1; then
|
||||
for _ in {1..50}; do
|
||||
port=$(shuf -i "${start_port}-${end_port}" -n 1)
|
||||
if ! is_port_in_use "$port"; then
|
||||
echo "$port"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
for port in $(seq "$start_port" "$end_port"); do
|
||||
if ! is_port_in_use "$port"; then
|
||||
echo "$port"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
resolve_port_value() {
|
||||
local name="$1"
|
||||
local value="$2"
|
||||
local resolved
|
||||
|
||||
if [ -z "$value" ] || [ "$value" = "auto" ]; then
|
||||
resolved=$(find_available_port)
|
||||
if [ -z "$resolved" ]; then
|
||||
return 1
|
||||
fi
|
||||
echo -e "\033[33m[WARN] ${name} 端口已自动分配为 ${resolved}\033[0m" >&2
|
||||
echo "$resolved"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$value" =~ ^[0-9]+$ ]]; then
|
||||
if is_port_in_use "$value"; then
|
||||
resolved=$(find_available_port)
|
||||
if [ -n "$resolved" ]; then
|
||||
echo -e "\033[33m[WARN] ${name} 端口 ${value} 已被占用,已自动切换为 ${resolved}\033[0m" >&2
|
||||
echo "$resolved"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$value"
|
||||
}
|
||||
|
||||
resolve_host_port() {
|
||||
local name="$1"
|
||||
local raw="$2"
|
||||
local default_host="$3"
|
||||
local host
|
||||
local port
|
||||
|
||||
if [ "$raw" = "auto" ] || [ -z "$raw" ]; then
|
||||
host="$default_host"
|
||||
port="auto"
|
||||
else
|
||||
if [[ "$raw" == *:* ]]; then
|
||||
host="${raw%:*}"
|
||||
port="${raw##*:}"
|
||||
else
|
||||
host="$default_host"
|
||||
port="$raw"
|
||||
fi
|
||||
fi
|
||||
|
||||
port=$(resolve_port_value "$name" "$port") || return 1
|
||||
echo "${host}:${port}"
|
||||
}
|
||||
Reference in New Issue
Block a user