|
1 | 1 | #!/bin/bash |
2 | 2 |
|
3 | | -# 检查是否提供了文件名作为参数 |
| 3 | +# ================= 配置区域 ================= |
| 4 | +THREADS=100 # 并发线程数 (根据网络状况调整,建议 50-100) |
| 5 | +TIMEOUT=3 # 单个连接超时时间 (秒) |
| 6 | +OUTPUT_MAIN="trackers_best.txt" |
| 7 | +OUTPUT_ARIA2="trackers_best_aria2.txt" |
| 8 | +# =========================================== |
| 9 | + |
4 | 10 | if [ "$#" -ne 1 ]; then |
5 | 11 | echo "Usage: $0 <file>" |
6 | 12 | exit 1 |
7 | 13 | fi |
8 | 14 |
|
9 | | -input_file="$1" |
10 | | -# 输出文件定义 |
11 | | -output_file_main="trackers_best.txt" |
12 | | -output_file_http="trackers_best_http.txt" |
13 | | -output_file_https="trackers_best_https.txt" |
14 | | -output_file_udp="trackers_best_udp.txt" |
15 | | -output_file_wss="trackers_best_wss.txt" |
16 | | -output_file_aria2="trackers_best_aria2.txt" # 新增 Aria2 输出文件 |
17 | | - |
18 | | -# 检查文件是否存在 |
19 | | -if [ ! -f "$input_file" ]; then |
20 | | - echo "Error: File not found." |
| 15 | +INPUT_FILE="$1" |
| 16 | + |
| 17 | +# 检查依赖 |
| 18 | +if ! command -v xargs &> /dev/null; then |
| 19 | + echo "Error: xargs is required." |
21 | 20 | exit 1 |
22 | 21 | fi |
23 | 22 |
|
24 | | -# 清空所有输出文件 |
25 | | -> "$output_file_main" |
26 | | -> "$output_file_http" |
27 | | -> "$output_file_https" |
28 | | -> "$output_file_udp" |
29 | | -> "$output_file_wss" |
30 | | -> "$output_file_aria2" |
31 | | - |
32 | | -echo "Starting connectivity test..." |
33 | | - |
34 | | -# 过滤黑名单并开始循环 |
35 | | -{ |
36 | | - if [ -f "blackstr.txt" ]; then |
37 | | - grep -v -F -f blackstr.txt "$input_file" |
38 | | - else |
39 | | - cat "$input_file" |
40 | | - fi |
41 | | -} | while IFS= read -r tracker; do |
42 | | - # 忽略空行 |
43 | | - [ -z "$tracker" ] && continue |
44 | | - |
45 | | - protocol=$(echo "$tracker" | grep -oE '^[a-z]+') |
46 | | - is_alive=0 |
| 23 | +# 核心检测函数 (将被导出供 xargs 调用) |
| 24 | +check_tracker() { |
| 25 | + local tracker="$1" |
| 26 | + local timeout="$2" |
| 27 | + local protocol=$(echo "$tracker" | grep -oE '^[a-z]+') |
47 | 28 |
|
48 | 29 | case $protocol in |
49 | | - http) |
50 | | - if curl -s -f -m 1 "$tracker" &>/dev/null; then |
51 | | - echo -e "\033[32mSuccess\033[0m: $tracker" |
52 | | - echo "$tracker" >> "$output_file_main" |
53 | | - echo "$tracker" >> "$output_file_http" |
54 | | - is_alive=1 |
55 | | - else |
56 | | - echo -e "\033[31mFailed\033[0m: $tracker" |
57 | | - fi |
58 | | - ;; |
59 | | - https) |
60 | | - if curl -s -f -m 1 "$tracker" &>/dev/null; then |
61 | | - echo -e "\033[32mSuccess\033[0m: $tracker" |
62 | | - echo "$tracker" >> "$output_file_main" |
63 | | - echo "$tracker" >> "$output_file_https" |
64 | | - is_alive=1 |
65 | | - else |
66 | | - echo -e "\033[31mFailed\033[0m: $tracker" |
| 30 | + http|https) |
| 31 | + # 使用 curl 检测,-I 仅请求头部加快速度 |
| 32 | + if curl -s -f -m "$timeout" "$tracker" &>/dev/null; then |
| 33 | + echo "$tracker" |
67 | 34 | fi |
68 | 35 | ;; |
69 | 36 | udp) |
70 | | - host=$(echo "$tracker" | cut -d'/' -f3) |
71 | | - port=$(echo "$host" | cut -d':' -f2) |
72 | | - host=$(echo "$host" | cut -d':' -f1) |
73 | | - # nc 增加 -w 1 超时 |
74 | | - if nc -zuv -w 1 "$host" "$port" &>/dev/null; then |
75 | | - echo -e "\033[32mSuccess\033[0m: $tracker" |
76 | | - echo "$tracker" >> "$output_file_main" |
77 | | - echo "$tracker" >> "$output_file_udp" |
78 | | - is_alive=1 |
79 | | - else |
80 | | - echo -e "\033[31mFailed\033[0m: $tracker" |
| 37 | + local host=$(echo "$tracker" | cut -d'/' -f3 | cut -d':' -f1) |
| 38 | + local port=$(echo "$tracker" | cut -d'/' -f3 | cut -d':' -f2) |
| 39 | + # nc 检测 UDP |
| 40 | + if nc -zuv -w "$timeout" "$host" "$port" &>/dev/null; then |
| 41 | + echo "$tracker" |
81 | 42 | fi |
82 | 43 | ;; |
83 | 44 | wss) |
84 | | - host=$(echo "$tracker" | sed 's|wss://||' | cut -d'/' -f1) |
85 | | - port=$(echo "$host" | cut -d':' -f2) |
86 | | - if [ "$port" = "$host" ]; then |
87 | | - port=443 |
88 | | - host=$(echo "$host" | cut -d':' -f1) |
| 45 | + # 优先使用 wscat (如果你安装了 node-ws),否则用 nc |
| 46 | + if command -v wscat &> /dev/null; then |
| 47 | + # wscat 连接测试 |
| 48 | + if wscat -c "$tracker" --no-check -w "$timeout" -x '{"close": 1}' &>/dev/null; then |
| 49 | + echo "$tracker" |
| 50 | + fi |
89 | 51 | else |
| 52 | + # 回退到 TCP 端口测试 |
| 53 | + local host=$(echo "$tracker" | sed 's|wss://||' | cut -d'/' -f1) |
| 54 | + local port=$(echo "$host" | cut -d':' -f2) |
| 55 | + [ "$port" = "$host" ] && port=443 && host=$(echo "$host" | cut -d':' -f1) |
90 | 56 | host=$(echo "$host" | cut -d':' -f1) |
91 | | - fi |
92 | | - |
93 | | - if nc -zv -w 1 "$host" "$port" &>/dev/null; then |
94 | | - echo -e "\033[32mSuccess\033[0m: $tracker" |
95 | | - echo "$tracker" >> "$output_file_main" |
96 | | - echo "$tracker" >> "$output_file_wss" |
97 | | - is_alive=1 |
98 | | - else |
99 | | - echo -e "\033[31mFailed\033[0m: $tracker" |
| 57 | + |
| 58 | + if nc -zv -w "$timeout" "$host" "$port" &>/dev/null; then |
| 59 | + echo "$tracker" |
| 60 | + fi |
100 | 61 | fi |
101 | 62 | ;; |
102 | | - *) |
103 | | - echo "Unknown protocol: $protocol" |
104 | | - ;; |
105 | 63 | esac |
106 | | -done |
| 64 | +} |
| 65 | + |
| 66 | +# 导出函数和变量供子 shell 使用 |
| 67 | +export -f check_tracker |
| 68 | +export TIMEOUT |
107 | 69 |
|
108 | | -# 生成 Aria2 格式 (将测试通过的列表合并为逗号分隔字符串) |
109 | | -if [ -s "$output_file_main" ]; then |
110 | | - echo "Generating Aria2 format..." |
111 | | - paste -sd "," "$output_file_main" > "$output_file_aria2" |
| 70 | +echo "Starting Multi-threaded testing ($THREADS threads)..." |
| 71 | +echo "Timeout set to ${TIMEOUT}s per tracker." |
| 72 | + |
| 73 | +# 准备临时文件 |
| 74 | +TEMP_VALID_LIST=$(mktemp) |
| 75 | + |
| 76 | +# =========================================== |
| 77 | +# 1. 预处理 + 多线程并行执行 |
| 78 | +# =========================================== |
| 79 | +# 逻辑: |
| 80 | +# 1. 读取文件 |
| 81 | +# 2. 过滤黑名单 |
| 82 | +# 3. xargs -P 启动多线程 |
| 83 | +# 4. 将成功的结果写入临时文件 |
| 84 | +{ |
| 85 | + if [ -f "blackstr.txt" ]; then |
| 86 | + grep -v -F -f blackstr.txt "$INPUT_FILE" |
| 87 | + else |
| 88 | + cat "$INPUT_FILE" |
| 89 | + fi |
| 90 | +} | tr -d '\r' | sort -u | \ |
| 91 | +xargs -P "$THREADS" -n 1 -I {} bash -c 'check_tracker "{}" "$TIMEOUT"' >> "$TEMP_VALID_LIST" |
| 92 | + |
| 93 | +# =========================================== |
| 94 | +# 2. 结果分类与文件生成 |
| 95 | +# =========================================== |
| 96 | +echo "Testing complete. Categorizing results..." |
| 97 | + |
| 98 | +# 清空旧文件 |
| 99 | +> "$OUTPUT_MAIN" |
| 100 | +> "trackers_best_http.txt" |
| 101 | +> "trackers_best_https.txt" |
| 102 | +> "trackers_best_udp.txt" |
| 103 | +> "trackers_best_wss.txt" |
| 104 | + |
| 105 | +# 统计数量 |
| 106 | +count=0 |
| 107 | + |
| 108 | +if [ -s "$TEMP_VALID_LIST" ]; then |
| 109 | + # 保存总表 |
| 110 | + sort -u "$TEMP_VALID_LIST" > "$OUTPUT_MAIN" |
| 111 | + |
| 112 | + # 分类保存 |
| 113 | + grep "^http://" "$OUTPUT_MAIN" > "trackers_best_http.txt" |
| 114 | + grep "^https://" "$OUTPUT_MAIN" > "trackers_best_https.txt" |
| 115 | + grep "^udp://" "$OUTPUT_MAIN" > "trackers_best_udp.txt" |
| 116 | + grep "^wss://" "$OUTPUT_MAIN" > "trackers_best_wss.txt" |
| 117 | + |
| 118 | + # 生成 Aria2 格式 |
| 119 | + paste -sd "," "$OUTPUT_MAIN" > "$OUTPUT_ARIA2" |
| 120 | + |
| 121 | + count=$(wc -l < "$OUTPUT_MAIN") |
| 122 | +else |
| 123 | + > "$OUTPUT_ARIA2" |
112 | 124 | fi |
113 | 125 |
|
114 | | -echo "Testing complete." |
115 | | -echo "Best trackers saved to $output_file_main" |
116 | | -echo "Aria2 format saved to $output_file_aria2" |
| 126 | +# 清理临时文件 |
| 127 | +rm "$TEMP_VALID_LIST" |
| 128 | + |
| 129 | +echo "------------------------------------------------" |
| 130 | +echo "Done! Found $count valid trackers." |
| 131 | +echo "1. Standard list: $OUTPUT_MAIN" |
| 132 | +echo "2. Aria2 format: $OUTPUT_ARIA2" |
| 133 | +echo "------------------------------------------------" |
0 commit comments