├── .github └── workflows │ └── build.yml ├── Dockerfile ├── README.md ├── docker_split.sh └── split.sh /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: "Build and push images" 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | Building: 8 | runs-on: ubuntu-latest 9 | name: "Build checking proxies images" 10 | env: 11 | DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} 12 | DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} 13 | DOCKERHUB_REPOSITORY: ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:latest 14 | 15 | steps: 16 | - name: Set up QEMU 17 | uses: docker/setup-qemu-action@v1.2.0 18 | 19 | - name: Set up Docker Buildx 20 | uses: docker/setup-buildx-action@v1.6.0 21 | 22 | - name: Login to DockerHub 23 | uses: docker/login-action@v1.14.1 24 | with: 25 | username: ${{ env.DOCKER_USERNAME }} 26 | password: ${{ env.DOCKER_PASSWORD }} 27 | 28 | - name: Build and push images to Docker hub 29 | uses: docker/build-push-action@v2.9.0 30 | with: 31 | push: true 32 | platforms: linux/amd64,linux/arm64,linux/s390x 33 | tags: ${{ env.DOCKERHUB_REPOSITORY }} 34 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | RUN apk add --no-cache curl 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 【各协议代理测活】 2 | 3 | * * * 4 | 5 | # 目录 6 | 7 | - [更新信息](README.md#更新信息) 8 | - [脚本特点](README.md#脚本特点) 9 | - [VPS 运行脚本](README.md#VPS-运行脚本) 10 | - [鸣谢](README.md#鸣谢下列作者的文章和项目) 11 | 12 | * * * 13 | 14 | ## 更新信息 15 | 2022.7.27 只测 socks 和 http 代理的 split.sh,并发处理,极快; 16 | 测综合的 docker_split.sh,由于vmess和vless涉及的组合太多,故需要慢慢完善 17 | 18 | ## 脚本特点 19 | * 代码开源透明,不会收集上报信息。原理:1、vps 本地安装官方 v2ray 和官方 alpine docker (升级 curl 指令),2、docker 通过 v2ray 连外网,3、逐一测试代理是否正确从 ip.sb 获取 IP ,4、最终把成功和失败的代理输出到 vps 本地文件 20 | * 支持多种主流协议: vmess, vless (XTLS除外), ss, socks5, https, trojan 21 | * 把经测试可用的代理,按用户指定个数分割为 N 个文件,不可用的代理输出为一个文件, 结果输出有提示 22 | * 脚本运行完会删除使用到的系统依赖、v2ray 和 alpine docker 23 | * 使用 docker_split 将会安装最新版 v2ray,请使用没有安装 xray 和 v2ray 的并且有 IPv4 网络的 VPS 上运行,以免冲突 24 | * 把所有的代理放入一个检测文件中,一行一个代理 25 | 26 | image 27 | 28 | image 29 | 30 | 31 | ## VPS 运行脚本 32 | 33 | ### 1. 只测 socks5 和 https 34 | ``` 35 | bash <(curl -sSL https://raw.githubusercontent.com/fscarmen/alive/main/split.sh) 36 | ``` 37 | 38 | ### 2. 综合测 vmess, vless, ss, socks5, https, trojan 39 | ``` 40 | bash <(curl -sSL https://raw.githubusercontent.com/fscarmen/alive/main/docker_split.sh) 41 | ``` 42 | 43 | ### 3.带参数 (pass parameter) 44 | | paremeter 参数 | value 值 | describe 具体动作说明 | 45 | | --------------|--------- | ------------------- | 46 | | -f | 代理文件路径 | 可以是绝对路径或者相对路径 | 47 | | -n | 指定个数可用代理为一个文件| 如填0即为不分割 | 48 | 49 | 举例: 检测文件为 test 里的 socks5 和 https 代理,并把可用的以 10 个为一个文件输出 50 | ``` 51 | bash <(curl -sSL https://raw.githubusercontent.com/fscarmen/alive/main/split.sh) -f test -n 10 52 | ``` 53 | 54 | ## 鸣谢下列作者的文章和项目 55 | 56 | 互联网永远不会忘记,但人们会。 57 | 58 | 技术文章和相关项目(排名不分先后): 59 | * StarOnTheSky: https://github.com/staronthesky 60 | * v2ray 项目团队: https://github.com/v2fly/v2ray-core 61 | * xray 项目团队: https://github.com/XTLS/Xray-core 62 | 63 | 服务提供(排名不分先后): 64 | * 获取公网 IP 及归属地查询: https://ip.sb/ 65 | -------------------------------------------------------------------------------- /docker_split.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 更新日期 2022-8-10 4 | 5 | # 定义 v2ray 的端口 6 | V2RAY_PORT='8080' 7 | NAME='check_proxy' 8 | 9 | # 最大后置测活次数 10 | CHECK_TIME='3' 11 | 12 | # 环境变量 13 | arry=('|' '/' '-' '\') 14 | 15 | # 传参 16 | while getopts “:N:n:F:f:” OPTNAME; do 17 | case "$OPTNAME" in 18 | 'N'|'n' ) NUM=$OPTARG;; 19 | 'F'|'f' ) FILE_PATH=$OPTARG;; 20 | esac 21 | done 22 | 23 | # 自定义字体彩色,read 函数,安装依赖函数 24 | red(){ echo -e "\033[31m\033[01m$@\033[0m"; } 25 | green(){ echo -e "\033[32m\033[01m$@\033[0m"; } 26 | yellow(){ echo -e "\033[33m\033[01m$@\033[0m"; } 27 | reading(){ read -rp "$(green "$1")" "$2"; } 28 | 29 | # 必须以root运行脚本 30 | [[ $(id -u) != 0 ]] && red " The script must be run as root, you can enter sudo -i and then download and run again." && exit 1 31 | 32 | # 判断 CPU 架构 33 | ARCHITECTURE=$(uname -m) 34 | case "$ARCHITECTURE" in 35 | aarch64 ) ARCH='arm64'; V2RAY='arm64-v8a';; 36 | x64|x86_64|amd64 ) ARCH='amd64'; V2RAY='64';; 37 | * ) red " ERROR: Unsupported architecture: $ARCHITECTURE\n" && exit 1;; 38 | esac 39 | 40 | # 判断操作系统 41 | CMD=( "$(grep -i pretty_name /etc/os-release 2>/dev/null | cut -d \" -f2)" 42 | "$(hostnamectl 2>/dev/null | grep -i system | cut -d : -f2)" 43 | "$(lsb_release -sd 2>/dev/null)" 44 | "$(grep -i description /etc/lsb-release 2>/dev/null | cut -d \" -f2)" 45 | "$(grep . /etc/redhat-release 2>/dev/null)" 46 | "$(grep . /etc/issue 2>/dev/null | cut -d \\ -f1 | sed '/^[ ]*$/d')" 47 | ) 48 | 49 | for i in "${CMD[@]}"; do SYS="$i" && [[ -n $SYS ]] && break; done 50 | 51 | REGEX=("debian" "ubuntu" "centos|red hat|kernel|oracle linux|alma|rocky" "'amazon linux'" "alpine" "arch linux") 52 | RELEASE=("Debian" "Ubuntu" "CentOS" "CentOS" "Alpine" "Arch") 53 | PACKAGE_INSTALL=("apt -y install" "apt -y install" "yum -y install" "yum -y install" "apk add -f" "pacman -S --noconfirm") 54 | PACKAGE_UNINSTALL=("apt -y autoremove" "apt -y autoremove" "yum -y autoremove" "yum -y autoremove" "apk del -f" "pacman -Rcnsu --noconfirm") 55 | 56 | for ((int=0; int<${#REGEX[@]}; int++)); do 57 | [[ $(tr '[:upper:]' '[:lower:]' <<< $SYS) =~ ${REGEX[int]} ]] && SYSTEM="${RELEASE[int]}" && break 58 | done 59 | 60 | # 输入检测文件路径和分割数量,并作初步检测 61 | [[ -z $FILE_PATH ]] && reading "\n Enter proxy file PATH. For example: /root/proxy.conf : " FILE_PATH 62 | [[ ! -e $FILE_PATH ]] && red " ERROR: Proxy file is not exist.\n" && exit 1 63 | [[ -z $(cat $FILE_PATH) ]] && red " ERROR: There is not any proxy.\n" && exit 1 64 | [[ -z $NUM ]] && reading "\n Enter quantity in splits.(Default is 999999): " NUM 65 | echo $NUM | grep -q "[^0-9]" && red " ERROR: $NUM is not an integer.\n" && exit 1 66 | [[ $NUM = 0 || -z $NUM ]] && NUM=999999 67 | 68 | # 脚本开始时间 69 | START=$(date +%s) 70 | 71 | # 安装 python3 以支持 json 格式, dos2unix 依赖,把 windows 文件格式化成 unix 使用的, wget 和 unzip 依赖 72 | DEPENDENCIES=(wget python3 unzip dos2unix) 73 | for i in ${DEPENDENCIES[@]}; do 74 | ! type -p $i >/dev/null 2>&1 && NEED_REMOVE=($i ${NEED_REMOVE[@]}) 75 | done 76 | [ ${#NEED_REMOVE[@]} != 0 ] && yellow "\n Install ${NEED_REMOVE[@]}\n" && ${PACKAGE_INSTALL[int]} ${NEED_REMOVE[@]} 77 | 78 | # 把 windows 文件格式化成 unix 使用的 79 | dos2unix $FILE_PATH 80 | 81 | # 宿主机安装 v2ray 82 | if ! systemctl is-enabled v2ray >/etc/null 2>&1; then 83 | yellow " \n Install v2ray \n " 84 | ${PACKAGE_UNINSTALL[int]} netfilter-persistent 85 | wget --no-check-certificate -O ./v2ray-linux-$V2RAY.zip https://github.com/v2fly/v2ray-core/releases/download/v4.45.0/v2ray-linux-$V2RAY.zip 86 | mkdir -p /etc/v2ray 87 | unzip -d /etc/v2ray v2ray-linux-*.zip 88 | cp /etc/v2ray/vpoint_vmess_freedom.json /etc/v2ray/config.json 89 | sed -i "s/ExecStart.*/ExecStart=\/etc\/v2ray\/v2ray -config \/etc\/v2ray\/config.json/g" /etc/v2ray/systemd/system/v2ray.service 90 | cp /etc/v2ray/systemd/system/v2ray.service /lib/systemd/system/ 91 | systemctl enable --now v2ray 92 | ! systemctl is-enabled v2ray >/etc/null 2>&1 && red "\n ERROR: v2ray doesn't work.\n" && exit 1 93 | rm -f v2ray-linux-*.zip 94 | fi 95 | 96 | # 创建 iptables 规则 97 | iptables -P INPUT ACCEPT 98 | iptables -P FORWARD ACCEPT 99 | iptables -P OUTPUT ACCEPT 100 | iptables -F 101 | iptables -t nat -D PREROUTING -s 172.20.0.1 -p tcp -j RETURN >/dev/null 2>&1 102 | iptables -t nat -D PREROUTING -s 172.20.0.0/16 -p tcp -j DNAT --to-destination 172.20.0.1:$V2RAY_PORT >/dev/null 2>&1 103 | iptables -t nat -A PREROUTING -s 172.20.0.1 -p tcp -j RETURN 104 | iptables -t nat -A PREROUTING -s 172.20.0.0/16 -p tcp -j DNAT --to-destination 172.20.0.1:$V2RAY_PORT 105 | 106 | # 宿主机安装 docker 和 wireguard 内核 107 | ! systemctl is-active docker >/dev/null 2>&1 && green " \n Install docker \n " && curl -sSL get.docker.com | sh 108 | systemctl is-enabled docker | grep -qv enabled && systemctl enable --now docker 109 | 110 | # 代理的话创建 172.20.0.0/16 网段,用与区分 warp 的 172.17.0.0/16 111 | [[ ! $(docker network list) =~ $NAME ]] && docker network create --subnet=172.20.0.0/16 $NAME 112 | 113 | # 创建一个测活容器 114 | docker pull fscarmen/alive:latest 115 | docker ps -a | awk '{print $NF}' | tail -n +2 | grep -q $NAME || 116 | docker run -dit --restart=always --name $NAME --net $NAME --ip 172.20.0.2 --sysctl net.ipv6.conf.all.disable_ipv6=0 --device /dev/net/tun --privileged --cap-add net_admin --cap-add sys_module --log-opt max-size=1m -v /lib/modules:/lib/modules fscarmen/alive:latest 117 | 118 | # 删除旧文件 119 | rm -f $FILE_PATH-* 120 | 121 | # 代理去重 122 | REMOVE_PROXIES=($(sort -u $FILE_PATH)) 123 | for ((u=0; u<$CHECK_TIME; u++)); do 124 | v=0 125 | PROXIES_NUM=${#REMOVE_PROXIES[@]} 126 | green "\n Check proxies alive $((u+1)) / $CHECK_TIME " 127 | [ "$u" = 0 ] && yellow " Check all the ${#REMOVE_PROXIES[@]} proxies. " || yellow " Recheck ${#REMOVE_PROXIES[@]} proxies. " 128 | for h in ${REMOVE_PROXIES[@]}; do 129 | PROXY_NOW="$h" 130 | ((v++)) 131 | index=$(( v % 4 )) 132 | VAL=$(( v * 100 / PROXIES_NUM )) 133 | printf " %c %3d%% %c\r" "${arry[$index]}" "$VAL" "${arry[$index]}" 134 | 135 | # socks 协议 136 | if echo "$h" | grep -q "^socks"; then 137 | if echo "$PROXY_NOW" | grep -q "@"; then 138 | TEST_USER=$(echo $PROXY_NOW | sed 's#socks.://##g' | awk -F [:@] '{print $1}') 139 | TEST_PASSWORD=$(echo $PROXY_NOW | sed 's#socks.://##g' | awk -F [:@] '{print $2}') 140 | TEST_IP=$(echo $PROXY_NOW | sed 's#socks.://##g' | awk -F [:@] '{print $3}') 141 | TEST_PORT=$(echo $PROXY_NOW | sed 's#socks.://##g' | awk -F [:@] '{print $4}') 142 | else 143 | TEST_IP=$(echo $PROXY_NOW | sed 's#socks.://##g' | awk -F [:] '{print $1}') 144 | TEST_PORT=$(echo $PROXY_NOW | sed 's#socks.://##g' | awk -F [:] '{print $2}') 145 | fi 146 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"mux\": { \"enabled\": false, \"concurrency\": 8 }, \"protocol\": \"socks\", \"settings\": { \"servers\": [ { \"address\": \"$TEST_IP\", \"port\": $TEST_PORT, \"users\": [ { \"user\": \"$TEST_USER\", \"pass\": \"$TEST_PASSWORD\" } ] } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 147 | 148 | elif 149 | # http(s) 协议 150 | echo "$PROXY_NOW" | grep -q "^http"; then 151 | if echo "$PROXY_NOW" | grep -q "@"; then 152 | TEST_USER=$(echo $PROXY_NOW | sed 's#http://##g' | awk -F [:@] '{print $1}') 153 | TEST_PASSWORD=$(echo $PROXY_NOW | sed 's#http://##g' | awk -F [:@] '{print $2}') 154 | TEST_IP=$(echo $PROXY_NOW | sed 's#http://##g' | awk -F [:@] '{print $3}') 155 | TEST_PORT=$(echo $PROXY_NOW | sed 's#http://##g' | awk -F [:@] '{print $4}') 156 | else 157 | TEST_IP=$(echo $PROXY_NOW | sed 's#http://##g' | awk -F [:] '{print $1}') 158 | TEST_PORT=$(echo $PROXY_NOW | sed 's#http://##g' | awk -F [:] '{print $2}') 159 | fi 160 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"mux\": { \"enabled\": false, \"concurrency\": 8 }, \"protocol\": \"http\", \"settings\": { \"servers\": [ { \"address\": \"$TEST_IP\", \"port\": $TEST_PORT, \"users\": [ { \"user\": \"$TEST_USER\", \"pass\": \"$TEST_PASSWORD\" } ] } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 161 | 162 | elif 163 | # vmess 协议 164 | echo "$PROXY_NOW" | grep -q "^vmess"; then 165 | 166 | # 传输协议为 ws 167 | if echo $PROXY_NOW | sed "s#vmess://##g" | base64 -d | grep -q '"net":[[:space:]]*"ws"'; then 168 | WS_ID=$(echo $PROXY_NOW | sed "s#vmess://##g" | base64 -d | python3 -m json.tool | grep '"id":' | cut -d\" -f4) 169 | WS_ADD=$(echo $PROXY_NOW | sed "s#vmess://##g" | base64 -d | python3 -m json.tool | grep '"add":' | cut -d\" -f4) 170 | WS_HOST=$(echo $PROXY_NOW | sed "s#vmess://##g" | base64 -d | python3 -m json.tool | grep '"host":' | cut -d\" -f4) 171 | WS_PATH=$(echo $PROXY_NOW | sed "s#vmess://##g" | base64 -d | python3 -m json.tool | grep '"path":' | cut -d\" -f4 | sed 's#%2[Ff]#/#g') 172 | WS_PORT=$(echo $PROXY_NOW | sed "s#vmess://##g" | base64 -d | python3 -m json.tool | grep '"port":' | grep -oP "\d+") 173 | 174 | if echo "$PROXY_NOW" | sed "s#vmess://##g" | base64 -d | python3 -m json.tool | grep -q '"tls":[[:space:]]*"tls"'; then 175 | # 安全类型为 tls,即为 vmess + ws + tls 176 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"mux\": { \"enabled\": false, \"concurrency\": 8 }, \"protocol\": \"vmess\", \"streamSettings\": { \"network\": \"ws\", \"security\": \"tls\", \"wsSettings\": { \"path\": \"$WS_PATH\", \"headers\": { \"host\": \"$WS_HOST\" } }, \"tlsSettings\": { \"serverName\": \"$WS_HOST\", \"allowInsecure\": false } }, \"settings\": { \"vnext\": [ { \"address\": \"$WS_ADD\", \"users\": [ { \"id\": \"$WS_ID\", \"alterId\": 0, \"level\": 0, \"security\": \"aes-128-gcm\" } ], \"port\": $WS_PORT } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 177 | else 178 | # 安全类型为 tls,即为 vmess + ws + none 179 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"mux\": { \"enabled\": false, \"concurrency\": 8 }, \"protocol\": \"vmess\", \"streamSettings\": { \"network\": \"ws\", \"security\": \"none\", \"wsSettings\": { \"path\": \"$WS_PATH\", \"headers\": { \"host\": \"$WS_HOST\" } } }, \"settings\": { \"vnext\": [ { \"address\": \"$WS_ADD\", \"users\": [ { \"id\": \"$WS_ID\", \"alterId\": 0, \"level\": 0, \"security\": \"aes-128-gcm\" } ], \"port\": $WS_PORT } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 180 | fi 181 | else 182 | # 传输协议为 tcp 183 | TCP_ID=$(echo $PROXY_NOW | sed "s#vmess://##g" | base64 -d | python3 -m json.tool | grep '"id":' | cut -d\" -f4) 184 | TCP_ADD=$(echo $PROXY_NOW | sed "s#vmess://##g" | base64 -d | python3 -m json.tool | grep '"add":' | cut -d\" -f4) 185 | TCP_PORT=$(echo $PROXY_NOW | sed "s#vmess://##g" | base64 -d | python3 -m json.tool | grep '"port":' | grep -oP "\d+") 186 | 187 | if echo "$PROXY_NOW" | sed "s#vmess://##g" | base64 -d | python3 -m json.tool | grep -q '"tls":[[:space:]]*"tls"'; then 188 | # 安全类型为 tls,即为 vmess + tcp + tls 189 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"mux\": { \"enabled\": false, \"concurrency\": 8 }, \"protocol\": \"vmess\", \"streamSettings\": { \"network\": \"tcp\", \"tcpSettings\": { \"header\": { \"type\": \"none\" } }, \"security\": \"tls\" , \"tlsSettings\": { \"allowInsecure\": false } }, \"settings\": { \"vnext\": [ { \"address\": \"$TCP_ADD\", \"users\": [ { \"id\": \"$TCP_ID\", \"alterId\": 0, \"level\": 0, \"security\": \"aes-128-gcm\" } ], \"port\": $TCP_PORT } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 190 | else 191 | # 类型为 tls,即为 vmess + tcp + none 192 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"mux\": { \"enabled\": false, \"concurrency\": 8 }, \"protocol\": \"vmess\", \"streamSettings\": { \"network\": \"tcp\", \"tcpSettings\": { \"header\": { \"type\": \"none\" } }, \"security\": \"none\" }, \"settings\": { \"vnext\": [ { \"address\": \"$TCP_ADD\", \"users\": [ { \"id\": \"$TCP_ID\", \"alterId\": 0, \"level\": 0, \"security\": \"aes-128-gcm\" } ], \"port\": $TCP_PORT } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 193 | fi 194 | fi 195 | elif 196 | # vless 协议 197 | echo "$PROXY_NOW" | grep -q "^vless"; then 198 | 199 | # 传输协议为 ws 200 | if echo $PROXY_NOW | grep -q 'type=ws'; then 201 | WS_ID=$(echo $PROXY_NOW | sed 's#vless://\([^@]\+\).*#\1#g') 202 | WS_ADD=$(echo $PROXY_NOW | sed 's#.*@\([^:]\+\).*#\1#g') 203 | WS_HOST=$(echo $PROXY_NOW | sed 's#.*host=\([^&#]\+\).*#\1#g') 204 | WS_PATH=$(echo $PROXY_NOW | sed 's#.*path=\([^&#]\+\).*#\1#g' | sed 's#%2[Ff]#/#g') 205 | WS_PORT=$(echo $PROXY_NOW | sed "s#.*:\([0-9]\+\)?.*#\1#g") 206 | 207 | if echo $PROXY_NOW | grep -q 'security=tls'; then 208 | # 安全类型为 tls,即为 vless + ws + tls 209 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"mux\": { \"enabled\": false, \"concurrency\": 8 }, \"protocol\": \"vless\", \"streamSettings\": { \"network\": \"ws\", \"security\": \"tls\", \"wsSettings\": { \"path\": \"$WS_PATH\", \"headers\": { \"host\": \"$WS_HOST\" } }, \"tlsSettings\": { \"serverName\": \"$WS_HOST\", \"allowInsecure\": false } }, \"settings\": { \"vnext\": [ { \"address\": \"$WS_ADD\", \"users\": [ { \"encryption\": \"none\", \"id\": \"$WS_ID\", \"level\": 0, \"flow\": \"\" } ], \"port\": $WS_PORT } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 210 | else 211 | # 安全类型为 tls,即为 vless + ws + none 212 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"mux\": { \"enabled\": false, \"concurrency\": 8 }, \"protocol\": \"vless\", \"streamSettings\": { \"network\": \"ws\", \"security\": \"none\", \"wsSettings\": { \"path\": \"$WS_PATH\", \"headers\": { \"host\": \"$WS_HOST\" } } }, \"settings\": { \"vnext\": [ { \"address\": \"$WS_ADD\", \"users\": [ { \"encryption\": \"none\", \"id\": \"$WS_ID\", \"level\": 0, \"flow\": \"\" } ], \"port\": $WS_PORT } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 213 | fi 214 | else 215 | # 传输协议为 tcp 216 | TCP_ID=$(echo $PROXY_NOW | sed 's#vless://\([^@]\+\).*#\1#g') 217 | TCP_ADD=$(echo $PROXY_NOW | sed 's#.*@\([^:]\+\).*#\1#g') 218 | TCP_PORT=$(echo $PROXY_NOW | sed "s#.*:\([0-9]\+\)?.*#\1#g") 219 | 220 | if echo $PROXY_NOW | grep -q 'security=tls'; then 221 | # 安全类型为 tcp, 即为 vless + tcp + tls 222 | TCP_SNI=$(echo $PROXY_NOW | sed 's#.*sni=\([^#]\+\).*#\1#g') 223 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"mux\": { \"enabled\": false, \"concurrency\": 8 }, \"protocol\": \"vless\", \"streamSettings\": { \"network\": \"tcp\", \"security\": \"tls\", \"tcpSettings\": { \"header\": { \"type\": \"none\" } }, \"tlsSettings\": { \"serverName\": \"$TCP_SNI\", \"allowInsecure\": false } }, \"tag\": \"proxy\", \"settings\": { \"vnext\": [ { \"address\": \"$TCP_ADD\", \"users\": [ { \"encryption\": \"none\", \"id\": \"$TCP_ID\", \"level\": 0, \"flow\": \"\" } ], \"port\": $TCP_PORT } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 224 | else 225 | # 类型为 tcp, 即为 vless + tcp + none 226 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"mux\": { \"enabled\": false, \"concurrency\": 8 }, \"protocol\": \"vless\", \"streamSettings\": { \"network\": \"tcp\", \"security\": \"none\", \"tcpSettings\": { \"header\": { \"type\": \"none\" } } }, \"settings\": { \"vnext\": [ { \"address\": \"$TCP_ADD\", \"users\": [ { \"encryption\": \"none\", \"id\": \"$TCP_ID\", \"level\": 0, \"flow\": \"\" } ], \"port\": $TCP_PORT } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 227 | fi 228 | fi 229 | elif 230 | # ss 协议 231 | echo "$PROXY_NOW" | grep -q "^ss://"; then 232 | # 新版格式带 @ 后面的地址和端口是明文的 233 | if echo "$PROXY_NOW" | grep -q "@"; then 234 | SS_METHOD=$(echo $PROXY_NOW | sed 's#ss://##g' | cut -d '@' -f1 | base64 -d 2>/dev/null | cut -d : -f1) 235 | SS_PASSWORD=$(echo $PROXY_NOW | sed 's#ss://##g' | cut -d '@' -f1 | base64 -d 2>/dev/null | cut -d : -f2) 236 | SS_ADD=$(echo $PROXY_NOW | sed "s/.*@\([^:]\+\).*/\1/g") 237 | SS_PORT=$(echo $PROXY_NOW | sed "s/.*:\([0-9]\+\).*/\1/g") 238 | else 239 | # 旧版本格式,全部经过 base64 encode 的 240 | SS_METHOD=$(echo $PROXY_NOW | sed 's#ss://\([^#]\+\).*#\1#g' | base64 -d 2>/dev/null | cut -d@ -f1 | cut -d: -f1) 241 | SS_PASSWORD=$(echo $PROXY_NOW | sed 's#ss://\([^#]\+\).*#\1#g' | base64 -d 2>/dev/null | cut -d@ -f1 | cut -d: -f2) 242 | SS_ADD=$(echo $PROXY_NOW | sed 's#ss://\([^#]\+\).*#\1#g' | base64 -d 2>/dev/null | cut -d@ -f2 | cut -d: -f1) 243 | SS_PORT=$(echo $PROXY_NOW | sed 's#ss://\([^#]\+\).*#\1#g' | base64 -d 2>/dev/null | cut -d@ -f2 | cut -d: -f2) 244 | fi 245 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"protocol\": \"shadowsocks\", \"streamSettings\": { \"network\": \"tcp\", \"tcpSettings\": { \"header\": { \"type\": \"none\" } }, \"security\": \"none\" }, \"settings\": { \"servers\": [ { \"port\": $SS_PORT, \"method\": \"$SS_METHOD\", \"password\": \"$SS_PASSWORD\", \"address\": \"$SS_ADD\", \"level\": 0, \"email\": \"\", \"ota\": false } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 246 | 247 | elif 248 | # trojan 协议 249 | echo "$PROXY_NOW" | grep -q "^trojan://"; then 250 | TROJAN_PASSWORD=$(echo $PROXY_NOW | sed 's#trojan://\([^#]\+\).*#\1#g' | cut -d@ -f1) 251 | TROJAN_ADD=$(echo $PROXY_NOW | sed "s#.*@\([^:]\+\).*#\1#g") 252 | TROJAN_PORT=$(echo $PROXY_NOW | sed "s#.*:\([0-9]\+\)?.*#\1#g") 253 | echo $PROXY_NOW | grep -q 'sni=' && TROJAN_SNI=$(echo $PROXY_NOW | sed "s#.*sni=\([^&#]\+\).*#\1#g") || TROJAN_SNI=$TROJAN_ADD 254 | JSON="{ \"inbounds\": [ { \"listen\": \"172.20.0.1\", \"port\": $V2RAY_PORT, \"protocol\": \"dokodemo-door\", \"settings\": { \"network\": \"tcp,udp\", \"followRedirect\": true }, \"sniffing\": { \"enabled\": true, \"destOverride\": [ \"http\", \"tls\" ] } } ], \"policy\": { \"levels\": { \"0\": { \"statsUserDownlink\": true, \"statsUserUplink\": true } }, \"system\": { \"statsInboundUplink\": true, \"statsInboundDownlink\": true } }, \"outbounds\": [ { \"tag\": \"proxy\", \"protocol\": \"trojan\", \"streamSettings\": { \"tcpSettings\": { \"header\": { \"type\": \"none\" } }, \"tlsSettings\": { \"serverName\": \"$TROJAN_SNI\", \"allowInsecure\": true }, \"security\": \"tls\", \"network\": \"tcp\" }, \"settings\": { \"servers\": [ { \"password\": \"$TROJAN_PASSWORD\", \"port\": $TROJAN_PORT, \"email\": \"\", \"level\": 0, \"address\": \"$TROJAN_ADD\" } ] } } ], \"routing\": { \"rules\": [ { \"type\": \"field\", \"outboundTag\": \"proxy\", \"source\": [ \"172.20.0.2\" ] }, { \"type\": \"field\", \"network\": \"tcp,udp\", \"outboundTag\": \"direct\" } ] } }" 255 | 256 | fi 257 | 258 | systemctl stop v2ray 259 | echo $JSON | python3 -m json.tool > /etc/v2ray/config.json 260 | sleep 1 261 | systemctl start v2ray 262 | sleep 1 263 | [[ $(docker exec -i $NAME curl -s4m$[u * 2 + 4] http://ip.sb | wc -l) = 1 ]] && 264 | OK_PROXIES=($(echo ${OK_PROXIES[@]}) $PROXY_NOW) && REMOVE_PROXIES=(${REMOVE_PROXIES[@]//$PROXY_NOW/}) 265 | done 266 | echo '' 267 | done 268 | 269 | # 删除 v2ray 270 | yellow " Remove temp files " 271 | systemctl disable --now v2ray 272 | rm -rf /etc/v2ray/ /lib/systemd/system/v2ray.service 273 | 274 | # 删除测试 docker 和网段名 275 | docker rm -f $NAME 276 | docker network rm $NAME 277 | docker rmi -f fscarmen/alive:latest 278 | 279 | # 删除防火墙相关规则 280 | iptables -t nat -D PREROUTING -s 172.20.0.1 -p tcp -j RETURN 281 | iptables -t nat -D PREROUTING -s 172.20.0.0/16 -p tcp -j DNAT --to-destination 172.20.0.1:$V2RAY_PORT 282 | 283 | # 删除本脚本安装的系统依赖 284 | [ ${#NEED_REMOVE[@]} != 0 ] && yellow "\n Uninstall ${NEED_REMOVE[@]}\n" && ${PACKAGE_UNINSTALL[int]} ${NEED_REMOVE[@]} 285 | 286 | # 结束时间,计算运行时长 287 | END=$(date +%s) 288 | RUNTIME=$[ END - START ] 289 | DAY=$[ RUNTIME / 86400 ] 290 | HOUR=$[ (RUNTIME % 86400 ) / 3600 ] 291 | MIN=$[ (RUNTIME % 86400 % 3600) / 60 ] 292 | SEC=$[ RUNTIME % 86400 % 3600 % 60 ] 293 | 294 | # 输入结果并分发文件 295 | [ "${#REMOVE_PROXIES[@]}" != 0 ] && echo "${REMOVE_PROXIES[@]}" | grep -oP "\K\S+" > $FILE_PATH-unavailable 296 | 297 | if [ "${#OK_PROXIES[@]}" = 0 ]; then 298 | red "\n No proxy now !\n Runing time: $DAY days $HOUR hours $MIN minutes $SEC seconds\n " && exit 299 | else 300 | echo "${OK_PROXIES[@]}" | grep -oP "\K\S+" > $FILE_PATH.available 301 | split -l $NUM $FILE_PATH.available -d $FILE_PATH- 302 | rm -f $FILE_PATH.available 303 | green " Result:\n ${#OK_PROXIES[@]} proxies are available in $(cat $FILE_PATH | sed "/^[[:space:]]*$/d" | wc -l). " 304 | ls | egrep -q "^$FILE_PATH-[0-9]+$" && green " Split into $(ls | egrep "^$FILE_PATH-[0-9]+$" | wc -l) files: $(ls | egrep "^$FILE_PATH-[0-9]+$" | paste -sd " "). " 305 | [ -e $FILE_PATH-unavailable ] && red " Unavailable proxies are in file: $FILE_PATH-unavailable. " 306 | green " Runing time: $DAY days $HOUR hours $MIN minutes $SEC seconds.\n " 307 | fi 308 | -------------------------------------------------------------------------------- /split.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 更新日期 2022-12-30 4 | 5 | # 传参 6 | while getopts “:N:n:F:f:” OPTNAME; do 7 | case "$OPTNAME" in 8 | 'N'|'n' ) NUM=$OPTARG;; 9 | 'F'|'f' ) FILE_PATH=$OPTARG;; 10 | esac 11 | done 12 | 13 | # 自定义字体彩色,read 函数,安装依赖函数 14 | red(){ echo -e "\033[31m\033[01m$@\033[0m"; } 15 | green(){ echo -e "\033[32m\033[01m$@\033[0m"; } 16 | yellow(){ echo -e "\033[33m\033[01m$@\033[0m"; } 17 | reading(){ read -rp "$(green "$1")" "$2"; } 18 | 19 | # 判断操作系统 20 | CMD=( "$(grep -i pretty_name /etc/os-release 2>/dev/null | cut -d \" -f2)" 21 | "$(hostnamectl 2>/dev/null | grep -i system | cut -d : -f2)" 22 | "$(lsb_release -sd 2>/dev/null)" 23 | "$(grep -i description /etc/lsb-release 2>/dev/null | cut -d \" -f2)" 24 | "$(grep . /etc/redhat-release 2>/dev/null)" 25 | "$(grep . /etc/issue 2>/dev/null | cut -d \\ -f1 | sed '/^[ ]*$/d')" 26 | ) 27 | 28 | for i in "${CMD[@]}"; do SYS="$i" && [[ -n $SYS ]] && break; done 29 | 30 | REGEX=("debian" "ubuntu" "centos|red hat|kernel|oracle linux|alma|rocky" "'amazon linux'" "alpine" "arch linux") 31 | RELEASE=("Debian" "Ubuntu" "CentOS" "CentOS" "Alpine" "Arch") 32 | PACKAGE_INSTALL=("apt -y install" "apt -y install" "yum -y install" "yum -y install" "apk add -f" "pacman -S --noconfirm") 33 | PACKAGE_UNINSTALL=("apt -y autoremove" "apt -y autoremove" "yum -y autoremove" "yum -y autoremove" "apk del -f" "pacman -Rcnsu --noconfirm") 34 | 35 | for ((int=0; int<${#REGEX[@]}; int++)); do 36 | [[ $(tr '[:upper:]' '[:lower:]' <<< $SYS) =~ ${REGEX[int]} ]] && SYSTEM="${RELEASE[int]}" && break 37 | done 38 | 39 | # 输入检测文件路径和分割数量,并作初步检测 40 | [[ -z $FILE_PATH ]] && reading "\n Enter proxy file PATH. For example: /root/proxy.conf : " FILE_PATH 41 | [[ ! -e $FILE_PATH ]] && red " ERROR: Proxy file is not exist.\n" && exit 1 42 | [[ -z $(cat $FILE_PATH) ]] && red " ERROR: There is not any proxy.\n" && exit 1 43 | [[ -z $NUM ]] && reading "\n Enter quantity in splits.(Default is 999999): " NUM 44 | echo $NUM | grep -q "[^0-9]" && red " ERROR: $NUM is not an integer.\n" && exit 1 45 | [[ $NUM = 0 || -z $NUM ]] && NUM=999999 46 | 47 | # 安装 python3 以支持 json 格式, dos2unix 依赖,把 windows 文件格式化成 unix 使用的, wget 和 unzip 依赖 48 | DEPENDENCIES=(curl dos2unix) 49 | for i in ${DEPENDENCIES[@]}; do 50 | ! type -p $i >/dev/null 2>&1 && NEED_REMOVE=($i ${NEED_REMOVE[@]}) 51 | done 52 | [ ${#NEED_REMOVE[@]} != 0 ] && yellow "\n Install ${NEED_REMOVE[@]}\n" && ${PACKAGE_INSTALL[int]} ${NEED_REMOVE[@]} 53 | 54 | # 把 windows 文件格式化成 unix 使用的 55 | dos2unix $FILE_PATH 56 | 57 | # 设定当前系统最大进程数 58 | ulimit -n 999999 59 | 60 | FILE=("$FILE_PATH" "$FILE_PATH-check1" "$FILE_PATH-check2") 61 | TEMP=("$FILE_PATH-check1" "$FILE_PATH-check2" "$FILE_PATH-unavailable") 62 | ECHO=("(1/3) 1st check the validity of proxies" "(2/3) 2nd recheck for unavailaxble proxies" "(3/3) 3rd recheck for unavailaxble proxies") 63 | TIME_OUT=("3" "7" "10") 64 | 65 | # 三次测代理可用性 66 | rm -f $FILE_PATH-* 67 | for ((b=0;b<${#FILE[@]};b++)); do 68 | unset CHECK_PROXY 69 | if [[ -n $(cat ${FILE[b]}) ]]; then 70 | yellow "\n ${ECHO[b]}\n" 71 | CHECK_PROXY=($(cat ${FILE[b]} | sed 's#^socks5://#socks5h://#g')) 72 | for a in "${CHECK_PROXY[@]}"; do 73 | { [ "$(curl -s4m${TIME_OUT[b]} -x $a ip.gs | wc -l)" = 1 ] && echo $a | sed 's#^socks5h://#socks5://#g' | tee -a $FILE_PATH.available >/dev/null 2>&1 || echo $a | sed 's#^socks5h://#socks5://#g' | tee -a ${TEMP[b]} >/dev/null 2>&1; }& 74 | done 75 | wait 76 | fi 77 | done 78 | 79 | # 删除本脚本安装的系统依赖 80 | [ ${#NEED_REMOVE[@]} != 0 ] && yellow "\n Uninstall ${NEED_REMOVE[@]}\n" && ${PACKAGE_UNINSTALL[int]} ${NEED_REMOVE[@]} 81 | 82 | # 输入结果并分发文件 83 | [[ ! -e $FILE_PATH.available ]] && red "\n No proxy now !\n" && rm -f ${TEMP[0]} ${TEMP[1]} && exit 84 | AVAILABLE=$(cat $FILE_PATH.available | wc -l) 85 | split -l $NUM $FILE_PATH.available -d $FILE_PATH- 86 | rm -f $FILE_PATH.available ${TEMP[0]} ${TEMP[1]} 87 | ls | egrep -q "^$FILE_PATH-[0-9]+$" && green " Result:\n Split $AVAILABLE proxies into $(ls | egrep "^$FILE_PATH-[0-9]+" | wc -l) files: $(ls | egrep "^$FILE_PATH-[0-9]+$" | paste -sd " "). " 88 | [ -e $FILE_PATH-unavailable ] && red " Unavailable proxies are in file: $FILE_PATH-unavailable. " 89 | --------------------------------------------------------------------------------