├── README.md └── onekey-tun2socks.sh /README.md: -------------------------------------------------------------------------------- 1 | # 给免费机一键添加Socks5 IPv4出口 2 | 3 | ## 更新日志 4 | v1.1.3 更新Alice家宽出口 5 | 6 | v1.1.2 移除失效的DNS64/NAT64服务器 7 | 8 | v1.1.1 更新Alice出口提示 9 | 10 | v1.1.0 添加自定义出口节点配置功能 11 | 12 | v1.0.9 过滤本地路由,防止回环 13 | 14 | v1.0.8 无聊的重构 15 | 16 | v1.0.7 下载tun2socks时使用自建DNS64/NAT64服务器,确保服务可控(仅Alice机型可用) 17 | 18 | v1.0.6 无聊的更新(重构了一些函数) 19 | 20 | v1.0.5 新增备用DNS64服务器组(@baipiaoking88) 21 | 22 | v1.0.4 修复原先systemd中的错误,并在启用tun设备后增加1秒延时(@baipiaoking88) 23 | 24 | v1.0.3 解决无IPv4的机子'RTNETLINK answers: Network is unreachable'报错(其实报错也无影响) 25 | 26 | v1.0.2 更新Alice出口(移除香港机房IP) 27 | 28 | ## 快速开始 29 | 30 | ### 以下命令适用于Alice的纯IPv6免费机 31 | ```bash 32 | curl -L https://raw.githubusercontent.com/hkfires/onekey-tun2socks/main/onekey-tun2socks.sh -o onekey-tun2socks.sh && chmod +x onekey-tun2socks.sh && sudo ./onekey-tun2socks.sh -i alice 33 | ``` 34 | 35 | > 注意事项:有IPv4的Alice机型使用Alice家宽Socks5出口时,需手动修改DNS(建议使用Alice V6的解锁DNS),由于家宽IP不在Alice V4 DNS的白名单内,会导致解析失败;机房Socks5出口不受此影响。 36 | 37 | ### 以下命令适用于LegendVPS的纯IPv6免费机(出口可能已失效) 38 | ```bash 39 | curl -L https://raw.githubusercontent.com/hkfires/onekey-tun2socks/main/onekey-tun2socks.sh -o onekey-tun2socks.sh && chmod +x onekey-tun2socks.sh && sudo ./onekey-tun2socks.sh -i legend 40 | ``` 41 | 42 | ### 卸载 43 | ```bash 44 | curl -L https://raw.githubusercontent.com/hkfires/onekey-tun2socks/main/onekey-tun2socks.sh -o onekey-tun2socks.sh && chmod +x onekey-tun2socks.sh && sudo ./onekey-tun2socks.sh -r 45 | ``` 46 | 47 | ## 手动下载运行 48 | 49 | 1. 下载脚本: 50 | ```bash 51 | curl -L https://raw.githubusercontent.com/hkfires/onekey-tun2socks/main/onekey-tun2socks.sh -o onekey-tun2socks.sh 52 | ``` 53 | 54 | 2. 添加执行权限: 55 | ```bash 56 | chmod +x onekey-tun2socks.sh 57 | ``` 58 | 59 | 3. 查看帮助信息: 60 | ```bash 61 | ./onekey-tun2socks.sh -h 62 | ``` 63 | 64 | 4. 运行脚本: 65 | ```bash 66 | # 安装 Alice 版本 67 | sudo ./onekey-tun2socks.sh -i alice 68 | 69 | # 安装 Legend 版本(出口可能已失效) 70 | sudo ./onekey-tun2socks.sh -i legend 71 | 72 | # 变更 Alice 出口 73 | sudo ./onekey-tun2socks.sh -s 74 | 75 | # 检查更新 76 | sudo ./onekey-tun2socks.sh -u 77 | 78 | # 卸载 79 | sudo ./onekey-tun2socks.sh -r 80 | ``` 81 | 82 | ## 服务管理 83 | 84 | 安装完成后,可以使用以下命令管理服务: 85 | 86 | ```bash 87 | # 查看服务状态 88 | systemctl status tun2socks.service 89 | 90 | # 启动服务 91 | systemctl start tun2socks.service 92 | 93 | # 停止服务 94 | systemctl stop tun2socks.service 95 | 96 | # 重启服务 97 | systemctl restart tun2socks.service 98 | 99 | # 查看日志 100 | journalctl -u tun2socks.service 101 | ``` 102 | -------------------------------------------------------------------------------- /onekey-tun2socks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | #================================================================================ 5 | # 常量和全局变量 6 | #================================================================================ 7 | VERSION="1.1.3" 8 | SCRIPT_URL="https://raw.githubusercontent.com/hkfires/onekey-tun2socks/main/onekey-tun2socks.sh" 9 | 10 | # 颜色定义 11 | RED='\033[0;31m' 12 | GREEN='\033[0;32m' 13 | YELLOW='\033[1;33m' 14 | BLUE='\033[0;34m' 15 | PURPLE='\033[0;35m' 16 | CYAN='\033[0;36m' 17 | NC='\033[0m' 18 | 19 | # 备用 DNS64 服务器 20 | ALTERNATE_DNS64_SERVERS=( 21 | "2a00:1098:2b::1" 22 | "2a01:4f8:c2c:123f::1" 23 | "2a01:4f9:c010:3f02::1" 24 | "2001:67c:2b0::4" 25 | "2001:67c:2b0::6" 26 | ) 27 | 28 | # 脚本操作的全局变量 29 | ACTION="" 30 | MODE="alice" # 默认安装模式 31 | 32 | #================================================================================ 33 | # 日志和工具函数 34 | #================================================================================ 35 | info() { echo -e "${BLUE}[信息]${NC} $1"; } 36 | success() { echo -e "${GREEN}[成功]${NC} $1"; } 37 | warning() { echo -e "${YELLOW}[警告]${NC} $1"; } 38 | error() { echo -e "${RED}[错误]${NC} $1"; } 39 | step() { echo -e "${PURPLE}[步骤]${NC} $1"; } 40 | 41 | require_root() { 42 | if [ "$EUID" -ne 0 ]; then 43 | error "请使用 root 权限运行此脚本,例如: sudo $0" 44 | exit 1 45 | fi 46 | } 47 | 48 | show_usage() { 49 | echo -e "${CYAN}使用方法:${NC} $0 [选项]" 50 | echo -e "${CYAN}选项:${NC}" 51 | echo -e " ${GREEN}-i, --install${NC} 安装 tun2socks (可选参数: alice, legend, 或 custom)" 52 | echo -e " ${GREEN}-r, --remove${NC} 卸载 tun2socks" 53 | echo -e " ${GREEN}-s, --switch${NC} 切换 Alice 模式的 Socks5 端口 (如果已安装)" 54 | echo -e " ${GREEN}-u, --update${NC} 检查并更新脚本" 55 | echo -e " ${GREEN}-h, --help${NC} 显示此帮助信息" 56 | echo 57 | echo -e "${CYAN}示例:${NC}" 58 | echo -e " $0 -i alice 安装 Alice 版本的 tun2socks" 59 | echo -e " $0 -i legend 安装 Legend 版本的 tun2socks" 60 | echo -e " $0 -i custom 使用自定义出口节点安装 tun2socks" 61 | echo -e " $0 -r 卸载 tun2socks" 62 | echo -e " $0 -s 切换 Alice 模式的 Socks5 端口" 63 | echo -e " $0 -u 检查脚本更新" 64 | } 65 | 66 | test_dns64_server() { 67 | local dns_server=$1 68 | step "正在测试DNS64服务器 $dns_server 的连通性..." 69 | 70 | if ping6 -c 3 -W 2 "$dns_server" &>/dev/null; then 71 | info "DNS64服务器 $dns_server 可达。" 72 | return 0 73 | else 74 | warning "DNS64服务器 $dns_server 不可达。" 75 | return 1 76 | fi 77 | } 78 | 79 | test_github_access() { 80 | step "正在测试GitHub访问..." 81 | if curl -s -m 10 https://github.com >/dev/null; then 82 | success "GitHub访问测试成功。" 83 | return 0 84 | else 85 | warning "GitHub访问测试失败。" 86 | return 1 87 | fi 88 | } 89 | 90 | restore_dns_config() { 91 | local resolv_conf=$1 92 | local resolv_conf_bak=$2 93 | local was_immutable=$3 94 | 95 | step "恢复原始 DNS 配置..." 96 | if [ -f "$resolv_conf_bak" ]; then 97 | mv "$resolv_conf_bak" "$resolv_conf" 98 | success "DNS 配置已恢复。" 99 | 100 | if [ "$was_immutable" = true ]; then 101 | info "重新锁定 /etc/resolv.conf..." 102 | chattr +i "$resolv_conf" || warning "无法重新锁定 /etc/resolv.conf。" 103 | success "锁定完成。" 104 | fi 105 | else 106 | warning "未找到 DNS 备份文件 ($resolv_conf_bak),无法自动恢复。" 107 | if [ "$was_immutable" = true ]; then 108 | warning "尝试锁定当前的 /etc/resolv.conf (注意:内容可能不是原始配置)..." 109 | chattr +i "$resolv_conf" || warning "无法锁定 /etc/resolv.conf。" 110 | fi 111 | fi 112 | } 113 | 114 | set_dns64_servers() { 115 | local mode=$1 116 | local resolv_conf=$2 117 | local was_immutable=$3 118 | local resolv_conf_bak=$4 119 | 120 | step "设置 DNS64 服务器(用于下载tun2socks)..." 121 | cat > "$resolv_conf" < "$resolv_conf" <&2 226 | 227 | local address port username password 228 | 229 | while true; do 230 | read -r -p "请输入Socks5服务器地址 (例如: 2001:db8::1 或 1.2.3.4): " address 231 | if [ -n "$address" ]; then 232 | break 233 | else 234 | error "服务器地址不能为空。" >&2 235 | fi 236 | done 237 | 238 | while true; do 239 | read -r -p "请输入Socks5服务器端口 (例如: 1080): " port 240 | if [[ "$port" =~ ^[0-9]+$ ]] && [ "$port" -ge 1 ] && [ "$port" -le 65535 ]; then 241 | break 242 | else 243 | error "无效的端口号,请输入 1 到 65535 之间的数字。" >&2 244 | fi 245 | done 246 | 247 | read -r -p "请输入用户名 (可选,留空则不使用): " username 248 | 249 | if [ -n "$username" ]; then 250 | read -r -p "请输入密码 (可选,留空则不使用): " password 251 | else 252 | password="" 253 | fi 254 | 255 | echo "$address" 256 | echo "$port" 257 | echo "$username" 258 | echo "$password" 259 | } 260 | 261 | select_alice_port() { 262 | local options=( 263 | "台湾家宽 #1:10001" 264 | "台湾家宽 #2:10002" 265 | "台湾家宽 #3:10003" 266 | "台湾家宽 #4:10004" 267 | "台湾家宽 #5:10005" 268 | "台湾家宽 #6:10006" 269 | "台湾家宽 #7:10007" 270 | "台湾家宽 #8:10008" 271 | ) 272 | echo >&2 273 | echo -e "${YELLOW}=========================================================${NC}" >&2 274 | echo -e "${GREEN}Alice Socks5 出口已统一为台湾家宽,端口范围 10001-10008。${NC}" >&2 275 | echo -e "${YELLOW}=========================================================${NC}" >&2 276 | echo >&2 277 | info "请为 Alice 模式选择 Socks5 出口端口 (全部为台湾家宽):" >&2 278 | for i in "${!options[@]}"; do 279 | local option_text="${options[$i]%%:*}" 280 | local port="${options[$i]#*:}" 281 | printf " %s) ${GREEN}%s (端口: %s)${NC}\n" "$((i+1))" "$option_text" "$port" >&2 282 | done 283 | 284 | local choice 285 | while true; do 286 | read -r -p "请输入选项 (1-${#options[@]},默认为1): " choice 287 | choice=${choice:-1} 288 | if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le ${#options[@]} ]; then 289 | local selected_option="${options[$((choice-1))]}" 290 | local port="${selected_option#*:}" 291 | info "已选择端口: $port (${selected_option%%:*})" >&2 292 | echo "$port" 293 | return 294 | else 295 | error "无效的选择,请输入 1 到 ${#options[@]} 之间的数字。" >&2 296 | fi 297 | done 298 | } 299 | 300 | cleanup_ip_rules() { 301 | step "正在清理残留的 IP 规则和路由..." 302 | 303 | ip rule del fwmark 438 lookup main pref 10 2>/dev/null || true 304 | ip -6 rule del fwmark 438 lookup main pref 10 2>/dev/null || true 305 | ip route del default dev tun0 table 20 2>/dev/null || true 306 | ip rule del lookup 20 pref 20 2>/dev/null || true 307 | ip rule del to 127.0.0.0/8 lookup main pref 16 2>/dev/null || true 308 | ip rule del to 10.0.0.0/8 lookup main pref 16 2>/dev/null || true 309 | ip rule del to 172.16.0.0/12 lookup main pref 16 2>/dev/null || true 310 | ip rule del to 192.168.0.0/16 lookup main pref 16 2>/dev/null || true 311 | 312 | info "正在循环清理优先级为 15 的规则..." 313 | while ip rule del pref 15 2>/dev/null; do 314 | info "删除了一条优先级为 15 的规则。" 315 | done 316 | 317 | success "IP 规则和路由清理完成。" 318 | } 319 | 320 | uninstall_tun2socks() { 321 | cleanup_ip_rules 322 | 323 | SERVICE_FILE="/etc/systemd/system/tun2socks.service" 324 | CONFIG_DIR="/etc/tun2socks" 325 | BINARY_PATH="/usr/local/bin/tun2socks" 326 | 327 | step "正在停止并禁用 tun2socks 服务..." 328 | if systemctl is-active --quiet tun2socks.service; then 329 | systemctl stop tun2socks.service 330 | success "tun2socks 服务已停止。" 331 | else 332 | info "tun2socks 服务未在运行。" 333 | fi 334 | 335 | if systemctl is-enabled --quiet tun2socks.service 2>/dev/null; then 336 | systemctl disable tun2socks.service 337 | success "tun2socks 服务已禁用开机自启。" 338 | else 339 | info "tun2socks 服务未设置开机自启。" 340 | fi 341 | 342 | step "正在移除 systemd 服务文件..." 343 | if [ -f "$SERVICE_FILE" ]; then 344 | rm -f "$SERVICE_FILE" 345 | success "systemd 服务文件 ($SERVICE_FILE) 已删除。" 346 | info "重新加载 systemd 配置..." 347 | systemctl daemon-reload 348 | info "重置服务失败状态 (如果存在)..." 349 | systemctl reset-failed tun2socks.service &>/dev/null || true 350 | else 351 | warning "systemd 服务文件 ($SERVICE_FILE) 未找到。" 352 | fi 353 | 354 | step "正在移除配置文件和目录..." 355 | if [ -d "$CONFIG_DIR" ]; then 356 | rm -rf "$CONFIG_DIR" 357 | success "配置文件目录 ($CONFIG_DIR) 已删除。" 358 | else 359 | warning "配置文件目录 ($CONFIG_DIR) 未找到。" 360 | fi 361 | 362 | step "正在移除 tun2socks 二进制文件..." 363 | if [ -f "$BINARY_PATH" ]; then 364 | rm -f "$BINARY_PATH" 365 | success "tun2socks 二进制文件 ($BINARY_PATH) 已删除。" 366 | else 367 | warning "tun2socks 二进制文件 ($BINARY_PATH) 未找到。" 368 | fi 369 | 370 | success "卸载完成。" 371 | } 372 | 373 | install_tun2socks() { 374 | cleanup_ip_rules 375 | 376 | step "检查 tun2socks 服务当前状态 (准备安装)..." 377 | if systemctl is-active --quiet tun2socks.service; then 378 | info "tun2socks 服务正在运行,将在安装前停止它。" 379 | if systemctl stop tun2socks.service; then 380 | success "tun2socks 服务已成功停止。" 381 | else 382 | warning "尝试停止 tun2socks 服务失败,安装将继续,但可能遇到问题。" 383 | fi 384 | else 385 | info "tun2socks 服务当前未运行。" 386 | fi 387 | 388 | RESOLV_CONF="/etc/resolv.conf" 389 | RESOLV_CONF_BAK="/etc/resolv.conf.bak" 390 | WAS_IMMUTABLE=false 391 | 392 | step "检查 /etc/resolv.conf 锁定状态..." 393 | if lsattr -d "$RESOLV_CONF" 2>/dev/null | grep -q -- '-i-'; then 394 | info "/etc/resolv.conf 文件当前被锁定 (immutable),尝试解锁..." 395 | chattr -i "$RESOLV_CONF" || { error "无法解锁 /etc/resolv.conf,请检查权限。"; exit 1; } 396 | WAS_IMMUTABLE=true 397 | success "解锁成功。" 398 | else 399 | info "/etc/resolv.conf 未被锁定。" 400 | fi 401 | 402 | step "备份当前 DNS 配置..." 403 | cp "$RESOLV_CONF" "$RESOLV_CONF_BAK" || { warning "备份 DNS 配置失败,可能文件不存在或权限不足。"; } 404 | 405 | if ! set_dns64_servers "$MODE" "$RESOLV_CONF" "$WAS_IMMUTABLE" "$RESOLV_CONF_BAK"; then 406 | exit 1 407 | fi 408 | 409 | REPO="heiher/hev-socks5-tunnel" 410 | INSTALL_DIR="/usr/local/bin" 411 | CONFIG_DIR="/etc/tun2socks" 412 | SERVICE_FILE="/etc/systemd/system/tun2socks.service" 413 | BINARY_PATH="$INSTALL_DIR/tun2socks" 414 | 415 | step "获取最新版本下载链接..." 416 | DOWNLOAD_URL=$(curl -s https://api.github.com/repos/$REPO/releases/latest | grep "browser_download_url" | grep "linux-x86_64" | cut -d '"' -f 4) 417 | 418 | if [ -z "$DOWNLOAD_URL" ]; then 419 | error "未找到适用于 linux-x86_64 的二进制文件下载链接,请检查网络或手动下载。" 420 | 421 | restore_dns_config "$RESOLV_CONF" "$RESOLV_CONF_BAK" "$WAS_IMMUTABLE" 422 | 423 | exit 1 424 | fi 425 | 426 | step "正在下载最新二进制文件:" 427 | info "$DOWNLOAD_URL" 428 | cleanup_on_fail() { 429 | trap - INT TERM EXIT 430 | warning "操作被中断或失败,正在执行清理..." 431 | restore_dns_config "$RESOLV_CONF" "$RESOLV_CONF_BAK" "$WAS_IMMUTABLE" 432 | exit 1 433 | } 434 | trap cleanup_on_fail INT TERM EXIT 435 | curl -L -o "$BINARY_PATH" "$DOWNLOAD_URL" 436 | trap - INT TERM EXIT 437 | 438 | restore_dns_config "$RESOLV_CONF" "$RESOLV_CONF_BAK" "$WAS_IMMUTABLE" 439 | 440 | chmod +x "$BINARY_PATH" 441 | 442 | step "创建配置文件..." 443 | mkdir -p "$CONFIG_DIR" 444 | CONFIG_FILE="$CONFIG_DIR/config.yaml" 445 | 446 | if [ "$MODE" = "alice" ]; then 447 | SOCKS_PORT=$(select_alice_port) 448 | 449 | cat > "$CONFIG_FILE" < "$CONFIG_FILE" < "$CONFIG_FILE" <<'EOF' 489 | tunnel: 490 | name: tun0 491 | mtu: 8500 492 | multi-queue: true 493 | ipv4: 198.18.0.1 494 | 495 | socks5: 496 | port: 8888 497 | address: '2001:db8:1234::6666' 498 | udp: 'udp' 499 | mark: 438 500 | EOF 501 | fi 502 | 503 | step "生成 systemd 服务文件 (tun2socks.service)..." 504 | 505 | if [ "$MODE" = "alice" ]; then 506 | MAIN_IP=$(ip -4 route get 1.1.1.1 2>/dev/null | awk '{print $7; exit}') 507 | RULE_ADD_FROM_MAIN_IP="" 508 | RULE_DEL_FROM_MAIN_IP="" 509 | 510 | if [ -n "$MAIN_IP" ]; then 511 | info "检测到 IPv4 地址: $MAIN_IP" 512 | info "将添加规则以允许源 IP 为 $MAIN_IP 的流量通过主路由表。" 513 | RULE_ADD_FROM_MAIN_IP="ExecStartPost=/sbin/ip rule add from $MAIN_IP lookup main pref 15" 514 | RULE_DEL_FROM_MAIN_IP="ExecStop=/sbin/ip rule del from $MAIN_IP lookup main pref 15" 515 | fi 516 | fi 517 | 518 | cat > "$SERVICE_FILE" </dev/null 559 | 560 | step "启动服务..." 561 | systemctl start tun2socks.service 562 | 563 | success "安装完成!" 564 | echo 565 | info "服务管理命令:" 566 | echo -e " ${GREEN}查看状态${NC}:systemctl status tun2socks.service" 567 | echo -e " ${GREEN}启动服务${NC}:systemctl start tun2socks.service" 568 | echo -e " ${GREEN}停止服务${NC}:systemctl stop tun2socks.service" 569 | echo -e " ${GREEN}重启服务${NC}:systemctl restart tun2socks.service" 570 | echo -e " ${GREEN}查看日志${NC}:journalctl -u tun2socks.service" 571 | echo -e " ${GREEN}实时查看日志${NC}:journalctl -u tun2socks.service -f" 572 | echo 573 | info "配置文件位置:" 574 | echo -e " ${GREEN}服务配置${NC}:/etc/systemd/system/tun2socks.service" 575 | echo -e " ${GREEN}程序配置${NC}:/etc/tun2socks/config.yaml" 576 | echo -e " ${GREEN}程序位置${NC}:/usr/local/bin/tun2socks" 577 | echo 578 | info "如需卸载,请运行:$0 -r" 579 | } 580 | 581 | switch_alice_port() { 582 | CONFIG_FILE="/etc/tun2socks/config.yaml" 583 | step "开始切换 Alice 模式 Socks5 端口..." 584 | 585 | if [ ! -f "$CONFIG_FILE" ]; then 586 | error "配置文件 $CONFIG_FILE 未找到。请先运行安装命令。" 587 | exit 1 588 | fi 589 | 590 | if ! grep -q "username: 'alice'" "$CONFIG_FILE"; then 591 | error "此切换功能仅适用于 Alice 模式的配置。" 592 | info "Legend 和 Custom 模式的配置需要手动修改: $CONFIG_FILE" 593 | exit 1 594 | fi 595 | 596 | current_port=$(grep -oP 'port: \K[0-9]+' "$CONFIG_FILE" | head -n 1) 597 | if [ -z "$current_port" ]; then 598 | error "无法从配置文件中读取当前端口。" 599 | exit 1 600 | fi 601 | info "当前 Socks5 端口: $current_port" 602 | 603 | NEW_SOCKS_PORT=$(select_alice_port) 604 | 605 | if [ "$NEW_SOCKS_PORT" = "$current_port" ]; then 606 | info "选择的端口 ($NEW_SOCKS_PORT) 与当前配置相同,无需更改。" 607 | exit 0 608 | fi 609 | 610 | step "正在停止 tun2socks 服务..." 611 | if systemctl stop tun2socks.service; then 612 | success "tun2socks 服务已停止。" 613 | else 614 | error "停止 tun2socks 服务失败。请检查服务状态。" 615 | fi 616 | 617 | step "正在更新配置文件 $CONFIG_FILE ..." 618 | sed -i "s/port: $current_port/port: $NEW_SOCKS_PORT/" "$CONFIG_FILE" 619 | if grep -q "port: $NEW_SOCKS_PORT" "$CONFIG_FILE"; then 620 | success "配置文件已更新,新端口为: $NEW_SOCKS_PORT" 621 | else 622 | error "更新配置文件失败。请检查 $CONFIG_FILE 文件。" 623 | warning "正在尝试以旧配置重启服务..." 624 | systemctl start tun2socks.service 625 | exit 1 626 | fi 627 | 628 | step "正在启动 tun2socks 服务..." 629 | if systemctl start tun2socks.service; then 630 | success "tun2socks 服务已启动。" 631 | success "Socks5 端口已成功切换至 $NEW_SOCKS_PORT。" 632 | else 633 | error "启动 tun2socks 服务失败。请使用 'systemctl status tun2socks.service' 和 'journalctl -u tun2socks.service' 查看详情。" 634 | error "配置文件可能已更新为新端口 $NEW_SOCKS_PORT,但服务启动失败。" 635 | exit 1 636 | fi 637 | } 638 | 639 | #================================================================================ 640 | # 主执行逻辑 641 | #================================================================================ 642 | 643 | parse_options() { 644 | local option_count=0 645 | 646 | if [ $# -eq 0 ]; then 647 | error "请指定一个操作。使用 -h 或 --help 查看帮助。" 648 | exit 1 649 | fi 650 | 651 | while [[ $# -gt 0 ]]; do 652 | case $1 in 653 | -i|--install) 654 | option_count=$((option_count + 1)) 655 | ACTION="install" 656 | if [[ $2 != -* ]] && [[ -n $2 ]]; then 657 | MODE="$2" 658 | shift 2 659 | else 660 | shift 661 | fi 662 | ;; 663 | -r|--remove) 664 | option_count=$((option_count + 1)) 665 | ACTION="uninstall" 666 | shift 667 | ;; 668 | -s|--switch) 669 | option_count=$((option_count + 1)) 670 | ACTION="switch" 671 | shift 672 | ;; 673 | -u|--update) 674 | option_count=$((option_count + 1)) 675 | ACTION="update" 676 | shift 677 | ;; 678 | -h|--help) 679 | show_usage 680 | exit 0 681 | ;; 682 | *) 683 | error "未知选项: $1" 684 | show_usage 685 | exit 1 686 | ;; 687 | esac 688 | done 689 | 690 | if [ "$option_count" -gt 1 ]; then 691 | error "请仅指定一个主要操作: 安装 (-i), 卸载 (-r), 切换端口 (-s), 或更新 (-u)" 692 | show_usage 693 | exit 1 694 | fi 695 | } 696 | 697 | dispatch_action() { 698 | case "$ACTION" in 699 | install) 700 | if [ "$MODE" != "alice" ] && [ "$MODE" != "legend" ] && [ "$MODE" != "custom" ]; then 701 | error "无效的安装模式 '$MODE',请使用 'alice', 'legend' 或 'custom'" 702 | exit 1 703 | fi 704 | install_tun2socks 705 | ;; 706 | uninstall) 707 | uninstall_tun2socks 708 | ;; 709 | switch) 710 | switch_alice_port 711 | ;; 712 | update) 713 | check_for_updates 714 | ;; 715 | *) 716 | error "没有指定操作或操作无效。" 717 | show_usage 718 | exit 1 719 | ;; 720 | esac 721 | } 722 | 723 | main() { 724 | require_root 725 | parse_options "$@" 726 | dispatch_action 727 | } 728 | 729 | # 脚本入口点 730 | main "$@" 731 | --------------------------------------------------------------------------------