speedtest
7
浏览
0
下载
0
点赞
0.0
评分
Linux Bash 多功能自更新测速脚本,下载并校验多个测速工具后执行网络测速。
开发语言Bash Shell
适配系统Linux / Debian / Ubuntu / CentOS / Arch Linux
源码类型自动化工具
版本区间speedtest-cli 1.2.0, bim-core 0.17.0, speedtest-go 1.6.11, librespeed-cli 1.0.10
适用行业运维
源码状态明文源码
演示数据无演示数据
适配面板CentOS / Ubuntu / Debian
源码体积微型(<10MB)
定时任务无需定时任务
多语言仅简体中文
💻 代码
Bash
#!/bin/bash
######### 自定义常量 ##########
_constant() {
script_version="v2024-04-25"
old_IFS="$IFS"
work_dir="./sp-github-i-abc"
node_set=""
node_set_1="https://raw.githubusercontent.com/i-abc/speedtest/node/all-node.txt"
node_set_2="https://asset.bash.icu/https://raw.githubusercontent.com/i-abc/speedtest/node/all-node-mirror.txt"
# url_1为官方源,url_2为镜像源,皆会进行SHA-256检测
# speedtest-cli,https://www.speedtest.net/zh-Hans/apps/cli
speedtest_cli_version="1.2.0"
speedtest_cli_tar_x86_64_sha256="5690596c54ff9bed63fa3732f818a05dbc2db19ad36ed68f21ca5f64d5cfeeb7"
speedtest_cli_tar_i386_sha256="9ff7e18dbae7ee0e03c66108445a2fb6ceea6c86f66482e1392f55881b772fe8"
speedtest_cli_tar_aarch64_sha256="3953d231da3783e2bf8904b6dd72767c5c6e533e163d3742fd0437affa431bd3"
speedtest_cli_tar_armhf_sha256="e45fcdebbd8a185553535533dd032d6b10bc8c64eee4139b1147b9c09835d08d"
speedtest_cli_tar_armel_sha256="629a455a2879224bd0dbd4b36d8c721dda540717937e4660b4d2c966029466bf"
speedtest_cli_tar_url=""
speedtest_cli_tar_url_1="https://install.speedtest.net/app/cli/ookla-speedtest-${speedtest_cli_version}-linux-${speedtest_cli_arch}.tgz"
speedtest_cli_tar_url_2="https://asset.bash.icu/https://raw.githubusercontent.com/i-abc/speedtest/asset/speedtest-cli/v${speedtest_cli_version}/ookla-speedtest-${speedtest_cli_version}-linux-${speedtest_cli_arch}.tgz"
# bim-core,https://github.com/veoco/bim-core
bim_core_version="0.17.0"
bim_core_tar_x86_64_sha256="109280fbf5a821bc56c2e83b906e65228ebc8436054b2e7861ca6db88f7e0330"
bim_core_tar_aarch64_sha256="fa62357f94050fbb7851d1bbb7e393d8e1301281ce03c43b37dae55cbf08c198"
bim_core_tar_url=""
bim_core_tar_url_1="https://github.com/veoco/bim-core/releases/download/v${bim_core_version}/bimc-${bim_core_arch}-unknown-linux-musl"
bim_core_tar_url_2="https://asset.bash.icu/https://github.com/veoco/bim-core/releases/download/v${bim_core_version}/bimc-${bim_core_arch}-unknown-linux-musl"
# speedtest-go,https://github.com/showwin/speedtest-go
speedtest_go_version="1.6.11"
speedtest_go_tar_x86_64_sha256="2603cf54513dd770353d66095a30b13d170d225a0a60fc07ee6d5f5a78e15a27"
speedtest_go_tar_i386_sha256="5ec1df89446aab656c0947c9028fa93b40ec83a4132e30b3dad978215103e294"
speedtest_go_tar_arm64_sha256="68b1be4cd6dbbd3d68216a106b578fd2bdf51b8606d3597743aefdb2f0234c24"
speedtest_go_tar_armv7_sha256="f30ba82ac4e6fd967302d505fa7380745d89a4ddcfb72f607b580ef507e5eb0a"
speedtest_go_tar_armv6_sha256="ccdc0a4281c193cccc027e7c2fb2b961e1eb3e4eab1dcf68b46bd0dafd2e895f"
speedtest_go_tar_url=""
speedtest_go_tar_url_1="https://github.com/showwin/speedtest-go/releases/download/v${speedtest_go_version}/speedtest-go_${speedtest_go_version}_Linux_${speedtest_go_arch}.tar.gz"
speedtest_go_tar_url_2="https://asset.bash.icu/https://github.com/showwin/speedtest-go/releases/download/v${speedtest_go_version}/speedtest-go_${speedtest_go_version}_Linux_${speedtest_go_arch}.tar.gz"
# librespeed-cli,https://github.com/librespeed/speedtest-cli
librespeed_cli_version="1.0.10"
librespeed_cli_tar_amd64_sha256="8e6d020c17e11dba73f0eb8a11f7ae6e3d96cdb307faf3c0ec13aa54e0cba055"
librespeed_cli_tar_386_sha256="0121bd4a21786d5964643b00a4193edfa15389050afe5579a290e67b706ef9eb"
librespeed_cli_tar_arm64_sha256="0ecbb98abb39f17bde2c0efae23f8446f4596c3a824aa6dda9b71723386b03ed"
librespeed_cli_tar_armv7_sha256="b121733b9a18aa646a16393396dd7fe59e8773420a38acb05b91652c4d6cb356"
librespeed_cli_tar_armv6_sha256="def98bbf0e79805411bca312e9e6bcddd12cd0abf4e6584a3ae05aa20c762b64"
librespeed_cli_tar_url=""
librespeed_cli_tar_url_1="https://github.com/librespeed/speedtest-cli/releases/download/v${librespeed_cli_version}/librespeed-cli_${librespeed_cli_version}_linux_${librespeed_cli_arch}.tar.gz"
librespeed_cli_tar_url_2="https://asset.bash.icu/https://github.com/librespeed/speedtest-cli/releases/download/v${librespeed_cli_version}/librespeed-cli_${librespeed_cli_version}_linux_${librespeed_cli_arch}.tar.gz"
# 配色
red='\033[1;31m'
green='\033[1;32m'
yellow='\033[1;33m'
blue='\033[1;34m'
purple='\033[1;35m'
cyan='\033[1;36m'
endc='\033[0m'
}
########## 进度条 ###########
_show_progress_bar() {
local bar="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
local i=0
local n="${#bar}"
while sleep 0.1; do
printf "\r ${green}测试进行中 %s${endc} " "${bar:i++%n:1}"
done
}
########## 横幅 ###########
_print_banner_1() {
echo "------------------------ 多功能 自更新 测速脚本 ------------------------"
echo -e " Version : ${green}${script_version}${endc}"
echo -e " Usage : ${yellow}bash <(curl -sL bash.icu/speedtest)${endc}"
echo -e " GitHub : ${green}https://github.com/i-abc/speedtest${endc}"
printf "%-72s\n" "-" | sed 's)\s)-)g'
}
_print_banner_2() {
if [ -s "$work_dir"/banner-custom.txt ]; then
cat "$work_dir"/banner-custom.txt
printf "%-72s\n" "-" | sed 's)\s)-)g'
fi
}
_print_banner_3() {
printf "%-s%-s%-s%-s%-s\n" "测速节点 " "下载/Mbps " "上传/Mbps " "延迟/ms " "抖动/ms"
}
_print_banner_4() {
printf "%-72s\n" "-" | sed 's)\s)-)g'
echo "系统时间:$(date +"%Y-%m-%d %H:%M:%S %Z")"
echo "北京时间: $(TZ=Asia/Shanghai date +"%Y-%m-%d %H:%M:%S %Z")"
printf "%-72s\n\n" "-" | sed 's)\s)-)g'
}
########## 检测是否为 root ##########
_check_user() {
sudo_flag=""
if [[ "${UID}" -eq 0 ]]; then
echo "当前用户是 root"
else
echo "当前用户不是 root"
sudo_flag="sudo"
fi
}
########## 确认架构及其对应版本的程序 ##########
_check_architecture() {
speedtest_cli_arch=""
bim_core_archh=""
speedtest_go_arch=""
librespeed_cli_arch=""
local arch
arch="$(uname -m)"
if [ "$arch" == "x86_64" ]; then
speedtest_cli_arch="x86_64"
bim_core_arch="x86_64"
speedtest_go_arch="x86_64"
librespeed_cli_arch="amd64"
elif [ "$arch" == "i386" ] || [ "$arch" == "i686" ]; then
speedtest_cli_arch="i386"
speedtest_go_arch="i386"
librespeed_cli_arch="386"
elif [ "$arch" == "armv8" ] || [ "$arch" == "armv8l" ] || [ "$arch" == "aarch64" ] || [ "$arch" == "arm64" ]; then
speedtest_cli_arch="aarch64"
bim_core_arch="aarch64"
speedtest_go_arch="arm64"
librespeed_cli_arch="arm64"
elif [ "$arch" == "armv7" ] || [ "$arch" == "armv7l" ]; then
speedtest_cli_arch="armhf"
speedtest_go_arch="armv7"
librespeed_cli_arch="armv7"
elif [ "$arch" == "armv6" ]; then
speedtest_cli_arch="armel"
speedtest_go_arch="armv6"
librespeed_cli_arch="armv6"
fi
}
########## 检测地区,指定下载源 ##########
_check_region() {
loc=$(curl -s -L "https://www.qualcomm.cn/cdn-cgi/trace" | awk -F'=' '/loc/{ print $2 }')
echo "loc: $loc"
if [ -z "$loc" ]; then
echo "使用镜像源"
node_set="$node_set_2"
speedtest_cli_tar_url="$speedtest_cli_tar_url_2"
bim_core_tar_url="$bim_core_tar_url_2"
speedtest_go_tar_url="$speedtest_go_tar_url_2"
librespeed_cli_tar_url="$librespeed_cli_tar_url_2"
elif [ "$loc" != "CN" ]; then
echo "使用默认源"
node_set="$node_set_1"
speedtest_cli_tar_url="$speedtest_cli_tar_url_1"
bim_core_tar_url="$bim_core_tar_url_1"
speedtest_go_tar_url="$speedtest_go_tar_url_1"
librespeed_cli_tar_url="$librespeed_cli_tar_url_1"
else
echo "使用镜像源"
node_set="$node_set_2"
speedtest_cli_tar_url="$speedtest_cli_tar_url_2"
bim_core_tar_url="$bim_core_tar_url_2"
speedtest_go_tar_url="$speedtest_go_tar_url_2"
librespeed_cli_tar_url="$librespeed_cli_tar_url_2"
fi
}
########## 检测某软件包是否安装,没安则自动安上,目前只支持RedHat、Debian系 ##########
_check_package() {
echo "正在检测所需的$1是否安装"
# 检测软件包是否安装
if ! command -v "$1"; then
# 确认包管理器并安装软件包
# RedHat
if command -v dnf; then
${sudo_flag} dnf install -y "$2"
elif command -v yum; then
${sudo_flag} yum install -y "$2"
# Debian
elif command -v apt; then
${sudo_flag} apt install -y "$2"
# Arch Linux
elif command -v pacman; then
${sudo_flag} pacman -S --noconfirm "$2"
else
echo "本机非RedHat、Debian、Arch Linux"
echo "暂不支持自动安装所需的软件包"
exit 1
fi
# 再次检测软件包是否安装
if ! command -v "$1"; then
echo "自动安装所需的$1失败"
echo "请手动安装$1后再执行本脚本"
exit 1
fi
fi
}
########## 创建工作目录 ##########
_make_dir() {
# 删除可能存在的残余文件
rm -rf "$work_dir"
# 创建目录
mkdir "$work_dir"
}
########## 下载程序 ##########
_download_tar() {
echo "$speedtest_cli_tar_url"
echo "speedtest-cli下载中"
curl --progress-bar -o "$work_dir"/speedtest-cli.tgz -L "$speedtest_cli_tar_url"
echo "$bim_core_tar_url"
echo "bim-core下载中"
[ -n "$bim_core_arch" ] && curl --progress-bar -o "$work_dir"/bim-core -L "$bim_core_tar_url"
echo "$speedtest_go_tar_url"
echo "speedtest-go下载中"
curl --progress-bar -o "$work_dir"/speedtest-go.tar.gz -L "$speedtest_go_tar_url"
echo "$librespeed_cli_tar_url"
echo "librespeed-cli下载中"
curl --progress-bar -o "$work_dir"/librespeed-cli.tar.gz -L "$librespeed_cli_tar_url"
}
########## 检测程序的SHA-256 ##########
_check_tar_sha256() {
local speedtest_cli_tar_download_sha256 bim_core_tar_download_sha256 speedtest_go_tar_download_sha256 librespeed_cli_tar_download_sha256
speedtest_cli_tar_download_sha256=$(sha256sum "$work_dir"/speedtest-cli.tgz | awk '{ print $1 }')
bim_core_tar_download_sha256=$(sha256sum "$work_dir"/bim-core | awk '{ print $1 }')
speedtest_go_tar_download_sha256=$(sha256sum "$work_dir"/speedtest-go.tar.gz | awk '{ print $1 }')
librespeed_cli_tar_download_sha256=$(sha256sum "$work_dir"/librespeed-cli.tar.gz | awk '{ print $1 }')
if [ "$speedtest_cli_tar_download_sha256" != "$(eval "echo \$speedtest_cli_tar_${speedtest_cli_arch}_sha256")" ]; then
printf "${red}%-s${endc}\n" "经检测,speedtest-cli的SHA-256与官方不符,方便的话欢迎到GitHub反馈"
exit 1
fi
if [ "$bim_core_tar_download_sha256" != "$(eval "echo \$bim_core_tar_${bim_core_arch}_sha256")" ] && [ -n "$bim_core_arch" ]; then
printf "${red}%-s${endc}\n" "经检测,bim-core的SHA-256与官方不符,方便的话欢迎到GitHub反馈"
exit 1
fi
if [ "$speedtest_go_tar_download_sha256" != "$(eval "echo \$speedtest_go_tar_${speedtest_go_arch}_sha256")" ]; then
printf "${red}%-s${endc}\n" "经检测,speedtest-go的SHA-256与官方不符,方便的话欢迎到GitHub反馈"
exit 1
fi
if [ "$librespeed_cli_tar_download_sha256" != "$(eval "echo \$librespeed_cli_tar_${librespeed_cli_arch}_sha256")" ]; then
printf "${red}%-s${endc}\n" "经检测,librespeed-cli的SHA-256与官方不符,方便的话欢迎到GitHub反馈"
exit 1
fi
}
########## 解压程序 ##########
_unzip_tar() {
tar -xf "$work_dir"/speedtest-cli.tgz -C "$work_dir"
tar -xf "$work_dir"/speedtest-go.tar.gz -C "$work_dir"
tar -xf "$work_dir"/librespeed-cli.tar.gz -C "$work_dir"
chmod +x "$work_dir"/bim-core
}
########## 获取节点列表 ##########
_get_node_list() {
# 节点集合
local node_url node_selection_1 node_selection_2 node_selection_3 first_line second_line
_print_banner_1
echo -e "${blue}↓ ↓ ↓ ↓ ↓ ↓ 测速节点列表 ↓ ↓ ↓ ↓ ↓ ↓${endc}"
echo -e "0. \033[1m自定义测速节点\033[0m"
curl -s -L "$node_set" | awk '$0!~/http/{print}'
printf "${yellow}%-s${endc}" "请输入您想选择的节点序号: "
read -r node_selection_1
# 某类节点
if [ "$node_selection_1" -ne 0 ]; then
node_url=$(curl -s -L "$node_set" | awk -F. "\$1== $node_selection_1 { getline; print }")
curl -o "$work_dir"/all-node.txt -L "$node_url"
elif [ "$node_selection_1" -eq 0 ]; then
printf "${yellow}%-s${endc}" "请输入您的自定义节点链接(http或本地绝对路径): "
read -r node_url_custom
# 判断自定义节点是网络链接还是本地文件
# 网络,http
if [[ "$node_url_custom" =~ \w{0}https?:// ]]; then
first_line="$(curl -s -L "$node_url_custom" | awk -F'.' NR==1'{ print $1 }')"
second_line="$(curl -s -L "$node_url_custom" | awk NR==2)"
if [ "$first_line" -eq 1 ] &>/dev/null && echo "$second_line" | grep -q -E "\w{0}https?://" &>/dev/null; then
node_set="$node_url_custom"
curl -s -L "$node_set" | awk '$0!~/http/{print}'
printf "${yellow}%-s${endc}" "请输入您想选择的节点序号: "
read -r node_selection_2
node_url=$(curl -s -L "$node_set" | awk -F. "\$1== $node_selection_2 { getline; print }")
curl -o "$work_dir"/all-node.txt -L "$node_url"
else
node_url="$node_url_custom"
curl -o "$work_dir"/all-node.txt -L "$node_url"
fi
# 本地,绝对路径
elif [[ "$node_url_custom" =~ \w{0}/{1} ]]; then
first_line="$(awk -F'.' NR==1'{ print $1 }' <"$node_url_custom")"
second_line="$(awk NR==2 <"$node_url_custom")"
if [ "$first_line" -eq 1 ] &>/dev/null && echo "$second_line" | grep -q -E "\w{0}/{1}" &>/dev/null; then
node_set="$node_url_custom"
awk '$0!~/^\//{print}' <"$node_set"
printf "${yellow}%-s${endc}" "请输入您想选择的节点序号: "
read -r node_selection_3
node_url="$(awk -F. "\$1== $node_selection_3 { getline; print }" <"$node_set")"
cp -f "$node_url" "$work_dir"/all-node.txt
else
node_url="$node_url_custom"
cp -f "$node_url" "$work_dir"/all-node.txt
fi
fi
fi
}
########## 分类节点 ###########
_classify_node() {
# 总行数
local row_num
row_num=$(wc -l "$work_dir"/all-node.txt | awk '{print $1}')
# 分类
for ((i = 1; i <= row_num; i++)); do
# 第一列
local first_column
first_column=$(awk -F, NR==${i}'{print $1}' "$work_dir"/all-node.txt)
# speedtest-cli
if [[ "$first_column" =~ "speedtest-cli" ]]; then
awk NR==${i} "$work_dir"/all-node.txt >>"$work_dir"/speedtest-cli-node.txt
# bim-core
elif [[ "$first_column" =~ "bim-core" ]] && [ -n "$bim_core_arch" ]; then
awk NR==${i} "$work_dir"/all-node.txt >>"$work_dir"/bim-core-node.txt
# speedtest-go
elif [[ "$first_column" =~ "speedtest-go" ]]; then
awk NR==${i} "$work_dir"/all-node.txt >>"$work_dir"/speedtest-go-node.txt
# librespeed-cli
elif [[ "$first_column" =~ "librespeed-cli" ]]; then
awk NR==${i} "$work_dir"/all-node.txt >>"$work_dir"/librespeed-cli-node.txt
# iperf3
elif [[ "$first_column" =~ "iperf3" ]]; then
awk NR==${i} "$work_dir"/all-node.txt >>"$work_dir"/iperf3-node.txt
# 自定义的横幅
elif [ "$first_column" != "" ]; then
awk NR==${i} "$work_dir"/all-node.txt >>"$work_dir"/banner-custom.txt
fi
done
}
########## speedtest-cli ##########
_speedtest_cli_test() {
# speedtest-cli的选项、参数
awk -F, '{ print $3 }' "$work_dir"/speedtest-cli-node.txt >"$work_dir"/speedtest-cli-option.txt
_filter_option_speedtest_cli "$work_dir"/speedtest-cli-option.txt "$work_dir"/speedtest-cli-option-filter.txt
# speedtest-cli测试、输出
option_para=""
count="1"
while IFS= read -r option_para; do
IFS="$old_IFS"
local node_name latency jitter download upload
local download_c="15" upload_c="15" latency_c="13" jitter_c="13"
# speedtest-cli测试
_show_progress_bar &
bar_pid="$!" && disown "$bar_pid"
timeout --foreground 70 ${work_dir}/speedtest --accept-license --accept-gdpr -f json-pretty ${option_para} >${work_dir}/speedtest-cli-${count}.json 2>${work_dir}/speedtest-cli-${count}-error.json
kill "$bar_pid" 2>/dev/null && printf "\r"
# speedtest-cli输出
if [ -s "$work_dir"/speedtest-cli-"$count".json ]; then
# 节点名称
node_name=$(awk -F, NR=="$count"'{ print $2 }' "$work_dir"/speedtest-cli-node.txt)
# 延迟,ms
latency="$(awk -F': |,' '/ping/{ getline; getline; print $2 }' "$work_dir"/speedtest-cli-"$count".json)"
_check_num "$latency" || latency=" 失败"
_check_num "$latency" || latency_c="15"
_check_num "$latency" && latency="$(printf "%.2f" "$latency") ms"
# 抖动,ms
jitter="$(awk -F': |,' '/ping/{ getline; print $2 }' "$work_dir"/speedtest-cli-"$count".json)"
_check_num "$jitter" || jitter=" 失败"
_check_num "$jitter" || jitter_c="15"
_check_num "$jitter" && jitter="$(printf "%.2f" "$jitter") ms"
# 下载速度,bps->Mbps
download="$(awk -F': |,' '/download/{ getline; print $2 }' "$work_dir"/speedtest-cli-"$count".json)"
_check_num "$download" || download=" 失败"
_check_num "$download" || download_c="17"
_check_num "$download" && download="$(echo "scale=2; $download / 125000" | bc)" && download="$(printf "%.2f" "$download") Mbps"
# 上传速度,bps->Mbps
upload="$(awk -F': |,' '/upload/{ getline; print $2 }' "$work_dir"/speedtest-cli-"$count".json)"
_check_num "$upload" || upload=" 失败"
_check_num "$upload" || upload_c="17"
_check_num "$upload" && upload="$(echo "scale=2; $upload / 125000" | bc)" && upload="$(printf "%.2f" "$upload") Mbps"
# 输出结果
[ -s "$work_dir"/speedtest-cli-"$count".json ] && _check_output
fi
if grep -q "Too many requests received" "$work_dir"/speedtest-cli-"$count"-error.json; then
echo "测速次数过多,暂时被限制,请过一段时间后再进行测试"
break
fi
count=$((count + 1))
done <"$work_dir"/speedtest-cli-option-filter.txt
}
########## bim-core ##########
_bim_core_test() {
# bim-core的选项、参数
awk -F, '{ print $3 }' "$work_dir"/bim-core-node.txt >"$work_dir"/bim-core-option.txt
_filter_option_bim_core "$work_dir"/bim-core-option.txt "$work_dir"/bim-core-option-filter.txt
# bim-core测试、输出
option_para=""
count="1"
while IFS= read -r option_para; do
IFS="$old_IFS"
local node_name latency jitter download upload
local download_c="15" upload_c="15" latency_c="13" jitter_c="13"
# bim-core测试
_show_progress_bar &
bar_pid="$!" && disown "$bar_pid"
timeout --foreground 70 ${work_dir}/bim-core ${option_para} >${work_dir}/bim-core-${count}.json 2>${work_dir}/bim-core-${count}-error.json
kill "$bar_pid" 2>/dev/null && printf "\r"
# bim-core输出
if [ -s "$work_dir"/bim-core-"$count".json ]; then
# 节点名称
node_name=$(awk -F, NR=="$count"'{ print $2 }' "$work_dir"/bim-core-node.txt)
# 延迟,ms
latency="$(awk '{ print $5 }' "$work_dir"/bim-core-"$count".json | awk -F',' '{ print $1 }')"
_check_num "$latency" || latency=" 失败"
_check_num "$latency" || latency_c="15"
_check_num "$latency" && latency="$(printf "%.2f" "$latency") ms"
# 抖动,ms
jitter="$(awk '{ print $6 }' "$work_dir"/bim-core-"$count".json)"
_check_num "$jitter" || jitter=" 失败"
_check_num "$jitter" || jitter_c="15"
_check_num "$jitter" && jitter="$(printf "%.2f" "$jitter") ms"
# 下载速度
download="$(awk '{ print $3 }' "$work_dir"/bim-core-"$count".json | awk -F',' '{ print $1 }')"
_check_num "$download" || download=" 失败"
_check_num "$download" || download_c="17"
_check_num "$download" && download="$(printf "%.2f" "$download") Mbps"
# 上传速度
upload="$(awk '{ print $1 }' "$work_dir"/bim-core-"$count".json | awk -F',' '{ print $1 }')"
_check_num "$upload" || upload=" 失败"
_check_num "$upload" || upload_c="17"
_check_num "$upload" && upload="$(printf "%.2f" "$upload") Mbps"
# 输出结果
[ -s "$work_dir"/bim-core-"$count".json ] && _check_output
fi
count=$((count + 1))
done <"$work_dir"/bim-core-option-filter.txt
}
########## speedtest-go ##########
_speedtest_go_test() {
# speedtest-go的选项、参数
awk -F, '{ print $3 }' "$work_dir"/speedtest-go-node.txt >"$work_dir"/speedtest-go-option.txt
_filter_option_speedtest_go "$work_dir"/speedtest-go-option.txt "$work_dir"/speedtest-go-option-filter.txt
# speedtest-go测试、输出
option_para=""
count="1"
while IFS= read -r option_para; do
IFS="$old_IFS"
local node_name latency jitter download upload
local download_c="15" upload_c="15" latency_c="13" jitter_c="13"
# speedtest-go测试
_show_progress_bar &
bar_pid="$!" && disown "$bar_pid"
timeout --foreground 70 ${work_dir}/speedtest-go ${option_para} >${work_dir}/speedtest-go-${count}.json 2>${work_dir}/speedtest-go-${count}-error.json
kill "$bar_pid" 2>/dev/null && printf "\r"
# speedtest-go输出
if [ -s "$work_dir"/speedtest-go-"$count".json ] && ! grep -q "Fatal" "$work_dir"/speedtest-go-"$count".json; then
# 节点名称
node_name="$(awk -F, NR=="$count"'{ print $2 }' "$work_dir"/speedtest-go-node.txt)"
# 延迟,ms
latency="$(awk -F' |ms|µs' '/Latency/{ print $3 }' "$work_dir"/speedtest-go-"$count".json)"
if awk -F'Latency: ' /Latency/'{ print $2 }' "$work_dir"/speedtest-go-"$count".json | awk -F' Jitter: ' '{ print $1 }' | grep -q µs; then
latency_unit="µs"
elif awk -F'Latency: ' /Latency/'{ print $2 }' "$work_dir"/speedtest-go-"$count".json | awk -F' Jitter: ' '{ print $1 }' | grep -q ms; then
latency_unit="ms"
fi
_check_num "$latency" || latency=" 失败"
_check_num "$latency" || latency_c="15"
_check_num "$latency" && latency="$(printf "%.2f" "$latency") $latency_unit"
# 抖动,ms
jitter="$(awk -F' |ms|µs' '/Jitter/{ print $6 }' "$work_dir"/speedtest-go-"$count".json)"
if awk -F'Jitter: ' /Jitter/'{ print $2 }' "$work_dir"/speedtest-go-"$count".json | awk -F' Min: ' '{ print $1 }' | grep -q µs; then
jitter_unit="µs"
elif awk -F'Jitter: ' /Jitter/'{ print $2 }' "$work_dir"/speedtest-go-"$count".json | awk -F' Min: ' '{ print $1 }' | grep -q ms; then
jitter_unit="ms"
fi
_check_num "$jitter" || jitter=" 失败"
_check_num "$jitter" || jitter_c="15"
_check_num "$jitter" && jitter="$(printf "%.2f" "$jitter") $jitter_unit"
# 下载、上传速度,Mbps
download="$(awk -F' |Mbps' '/Download/{ print $3 }' "$work_dir"/speedtest-go-"$count".json)"
_check_num "$download" || download=" 失败"
_check_num "$download" || download_c="17"
_check_num "$download" && download="$(printf "%.2f" "$download") Mbps"
upload="$(awk -F' |Mbps' '/Upload/{ print $3 }' "$work_dir"/speedtest-go-"$count".json)"
_check_num "$upload" || upload=" 失败"
_check_num "$upload" || upload_c="17"
_check_num "$upload" && upload="$(printf "%.2f" "$upload") Mbps"
_check_option "--no-upload" "$option_para" && upload=" 跳过"
_check_option "--no-upload" "$option_para" && upload_c="17"
_check_option "--no-download" "$option_para" && download=" 跳过"
_check_option "--no-download" "$option_para" && download_c="17"
# 输出结果
[ -s "$work_dir"/speedtest-go-"$count".json ] && _check_output
fi
count=$((count + 1))
done <"$work_dir"/speedtest-go-option-filter.txt
}
########## librespeed-cli ##########
_librespeed_cli_test() {
# librespeed-cli的选项、参数
awk -F, '{ print $3 }' "$work_dir"/librespeed-cli-node.txt >"$work_dir"/lbrespeed-cli-option.txt
_filter_option_librespeed_cli "$work_dir"/lbrespeed-cli-option.txt "$work_dir"/lbrespeed-cli-option-filter.txt
# librespeed-cli测试、输出
option_para=""
count="1"
while IFS= read -r option_para; do
IFS="$old_IFS"
local node_name latency jitter download upload
local download_c="15" upload_c="15" latency_c="13" jitter_c="13"
# librespeed-cli测试
_show_progress_bar &
bar_pid="$!" && disown "$bar_pid"
timeout --foreground 70 ${work_dir}/librespeed-cli --json ${option_para} >${work_dir}/librespeed-cli-${count}.json 2>${work_dir}/librespeed-cli-${count}-error.json
kill "$bar_pid" 2>/dev/null && printf "\r"
# librespeed-cli输出
if [ -s "$work_dir"/librespeed-cli-"$count".json ]; then
# 节点名称
node_name=$(awk -F, NR=="$count"'{ print $2 }' "$work_dir"/librespeed-cli-node.txt)
# 延迟,ms
latency="$(awk -F'"ping":' '{ print $2 }' "$work_dir"/librespeed-cli-"$count".json | awk -F',' '{ print $1 }')"
_check_num "$latency" || latency=" 失败"
_check_num "$latency" || latency_c="15"
_check_num "$latency" && latency="$(printf "%.2f" "$latency") ms"
# 抖动,ms
jitter="$(awk -F'"jitter":' '{ print $2 }' "$work_dir"/librespeed-cli-"$count".json | awk -F',' '{ print $1 }')"
_check_num "$jitter" || jitter=" 失败"
_check_num "$jitter" || jitter_c="15"
_check_num "$jitter" && jitter="$(printf "%.2f" "$jitter") ms"
# 下载、上传速度,Mbps
download="$(awk -F'"download":' '{ print $2 }' "$work_dir"/librespeed-cli-"$count".json | awk -F',' '{ print $1 }')"
_check_num "$download" || download=" 失败"
_check_num "$download" || download_c="17"
_check_num "$download" && download="$(printf "%.2f" "$download") Mbps"
upload="$(awk -F'"upload":' '{ print $2 }' "$work_dir"/librespeed-cli-"$count".json | awk -F',' '{ print $1 }')"
_check_num "$upload" || upload=" 失败"
_check_num "$upload" || upload_c="17"
_check_num "$upload" && upload="$(printf "%.2f" "$upload") Mbps"
_check_option "--no-upload" "$option_para" && upload=" 跳过"
_check_option "--no-upload" "$option_para" && upload_c="17"
_check_option "--no-download" "$option_para" && download=" 跳过"
_check_option "--no-download" "$option_para" && download_c="17"
# 输出结果
[ -s "$work_dir"/librespeed-cli-"$count".json ] && _check_output
fi
count=$((count + 1))
done <"$work_dir"/lbrespeed-cli-option-filter.txt
}
########## iperf3 ##########
_iperf3_test() {
# iperf3的选项、参数
awk -F',' '{ print $3 }' "$work_dir"/iperf3-node.txt >"$work_dir"/iperf3-option.txt
_filter_option_iperf3 "$work_dir"/iperf3-option.txt "$work_dir"/iperf3-option-filter.txt
# iperf3测试、输出
option_para=""
count="1"
while IFS= read -r option_para; do
IFS="$old_IFS"
local node_name download upload latency jitter
local download_c="15" upload_c="15" latency_c="13" jitter_c="13"
# iperf3测试
if _check_option "--up-and-down" "$option_para"; then
# 双向
option_para="$(echo "$option_para" | awk -F'--up-and-down' '{ print $1 $2 }')"
# 节点名称
node_name=$(awk -F, NR=="$count"'{ print $2 }' "$work_dir"/iperf3-node.txt)
# 延迟,ms
latency=" 跳过"
latency_c="15"
# 抖动,ms
jitter=" 跳过"
jitter_c="15"
# 上传
local i_busy
for ((i_busy = 1; i_busy <= 65; i_busy++)); do
_show_progress_bar &
bar_pid="$!" && disown "$bar_pid"
timeout --foreground 70 iperf3 -f m ${option_para} >${work_dir}/iperf3-${count}.json 2>${work_dir}/iperf3-${count}-error.json
kill "$bar_pid" 2>/dev/null && printf "\r"
if grep -q "busy" "$work_dir"/iperf3-"$count"-error.json; then
sleep 0.5
fi
if [ -s "$work_dir"/iperf3-"$count".json ]; then
break
fi
done
# 上传速度,Mbps
if [ -s "$work_dir"/iperf3-"$count".json ]; then
upload="$(awk '{ rows[NR] = $0 } END{ print rows[NR-3] }' "$work_dir"/iperf3-"$count".json | awk -F'Bytes ' '{ print $2 }' | awk '{ print $1 }')"
_check_num "$upload" || upload=" 失败"
_check_num "$upload" || upload_c="17"
_check_num "$upload" && upload="$(printf "%.2f" "$upload") Mbps"
else
upload=" 跳过" && upload_c="17"
fi
# 下载
for ((i_busy = 1; i_busy <= 65; i_busy++)); do
_show_progress_bar &
bar_pid="$!" && disown "$bar_pid"
timeout --foreground 70 iperf3 -f m -R ${option_para} >${work_dir}/iperf3-${count}.json 2>${work_dir}/iperf3-${count}-error.json
kill "$bar_pid" 2>/dev/null && printf "\r"
if grep -q "busy" "$work_dir"/iperf3-"$count"-error.json; then
sleep 0.5
fi
if [ -s "$work_dir"/iperf3-"$count".json ]; then
break
fi
done
# 下载速度,Mbps
if [ -s "$work_dir"/iperf3-"$count".json ]; then
download="$(awk '{ rows[NR] = $0 } END{ print rows[NR-2] }' "$work_dir"/iperf3-"$count".json | awk -F'Bytes ' '{ print $2 }' | awk '{ print $1 }')"
_check_num "$download" || download=" 失败"
_check_num "$download" || download_c="17"
_check_num "$download" && download="$(printf "%.2f" "$download") Mbps"
else
upload=" 跳过" && upload_c="17"
fi
# 输出结果
[ -s "$work_dir"/iperf3-"$count".json ] && _check_output
else
# 单向
for ((i_busy = 1; i_busy <= 65; i_busy++)); do
_show_progress_bar &
bar_pid="$!" && disown "$bar_pid"
timeout --foreground 70 iperf3 -f m ${option_para} >${work_dir}/iperf3-${count}.json 2>${work_dir}/iperf3-${count}-error.json
kill "$bar_pid" 2>/dev/null && printf "\r"
if grep -q "busy" "$work_dir"/iperf3-"$count"-error.json; then
sleep 0.5
fi
if [ -s "$work_dir"/iperf3-"$count".json ]; then
break
fi
done
# iperf3输出
if [ -s "$work_dir"/iperf3-"$count".json ]; then
# 节点名称
node_name=$(awk -F, NR=="$count"'{ print $2 }' "$work_dir"/iperf3-node.txt)
# 延迟,ms
latency=" 跳过"
latency_c="15"
# 抖动,ms
jitter=" 跳过"
jitter_c="15"
# 下载、上传速度,Mbps
upload="$(awk '{ rows[NR] = $0 } END{ print rows[NR-3] }' "$work_dir"/iperf3-"$count".json | awk -F'Bytes ' '{ print $2 }' | awk '{ print $1 }')"
_check_num "$upload" || upload=" 失败"
_check_num "$upload" || upload_c="17"
_check_num "$upload" && upload="$(printf "%.2f" "$upload") Mbps"
download="$(awk '{ rows[NR] = $0 } END{ print rows[NR-2] }' "$work_dir"/iperf3-"$count".json | awk -F'Bytes ' '{ print $2 }' | awk '{ print $1 }')"
_check_num "$download" || download=" 失败"
_check_num "$download" || download_c="17"
_check_num "$download" && download="$(printf "%.2f" "$download") Mbps"
_check_option "-R" "$option_para" && upload=" 跳过"
_check_option "-R" "$option_para" && upload_c="17"
_check_option "-R" "$option_para" || download=" 跳过"
_check_option "-R" "$option_para" || download_c="17"
# 输出结果
[ -s "$work_dir"/iperf3-"$count".json ] && _check_output
fi
fi
count=$((count + 1))
done <"$work_dir"/iperf3-option-filter.txt
}
########## 整理选项、参数 ##########
# 不带参数的选项,包括-/--
_filter_option_0_para() {
if [ "$(echo "$line_input" | awk "{ print $"$column_count" }")" == "$1" ] || [ "$(echo "$line_input" | awk "{ print $"$column_count" }")" == "$2" ]; then
line_output="$line_output $1"
fi
}
# 带一个参数的选项,包括-/--
_filter_option_1_para() {
if [ "$(echo "$line_input" | awk "{ print $"$column_count" }")" == "$1" ] || [ "$(echo "$line_input" | awk "{ print $"$column_count" }")" == "$2" ]; then
column_count=$((column_count + 1))
line_output="$line_output $1 $(echo "$line_input" | awk "{ print $"$column_count" }")"
fi
}
# bim-core专用,处理为链接的参数
_filter_option_bim_core_1() {
if [[ "$(echo "$line_input" | awk "{ print $"$column_count" }")" =~ http ]]; then
line_output="$line_output $(echo "$line_input" | awk "{ print $"$column_count" }")"
fi
}
# iperf3专用,处理-p选项
_filter_option_iperf3_1() {
local port
if [ "$(echo "$line_input" | awk "{ print $"$column_count" }")" == "-p" ] || [ "$(echo "$line_input" | awk "{ print $"$column_count" }")" == "--port" ]; then
column_count=$((column_count + 1))
port=$(echo "$line_input" | awk "{ print $"$column_count" }")
if [[ "$port" =~ ^[0-9]+$ ]]; then
# 一个端口
line_output="$line_output $1 $port"
else
# 多个端口,随机一个
port=$(shuf -n 1 -i $port)
line_output="$line_output $1 $port"
fi
fi
}
# speedtest-cli
_filter_option_speedtest_cli() {
local line_input line_output column_count column_all_count
local file_input="$1" file_output="$2"
while IFS= read -r line_input; do
IFS="$old_IFS"
line_output=""
column_all_count="$(echo "$line_input" | awk '{ print NF }')"
for ((column_count = 1; column_count <= column_all_count; column_count++)); do
_filter_option_1_para -s --server-id
_filter_option_1_para -o --host
done
echo "$line_output" >>"$file_output"
done <"$file_input"
}
# bim-core
_filter_option_bim_core() {
local line_input line_output column_count column_all_count
local file_input="$1" file_output="$2"
while IFS= read -r line_input; do
IFS="$old_IFS"
line_output=""
column_all_count="$(echo "$line_input" | awk '{ print NF }')"
for ((column_count = 1; column_count <= column_all_count; column_count++)); do
_filter_option_1_para -6 --ipv6
_filter_option_1_para -m --multi
_filter_option_bim_core_1
done
echo "$line_output" >>"$file_output"
done <"$file_input"
}
# speedtest-go
_filter_option_speedtest_go() {
local line_input line_output column_count column_all_count
local file_input="$1" file_output="$2"
while IFS= read -r line_input; do
IFS="$old_IFS"
line_output=""
column_all_count="$(echo "$line_input" | awk '{ print NF }')"
for ((column_count = 1; column_count <= column_all_count; column_count++)); do
_filter_option_1_para -s --server
_filter_option_1_para --custom-url --custom-url
_filter_option_1_para -t --thread
_filter_option_1_para --ping-mode --ping-mode
_filter_option_0_para -m --multi
_filter_option_0_para --no-download --no-download
_filter_option_0_para --no-upload --no-upload
done
echo "$line_output" >>"$file_output"
done <"$file_input"
}
# librespeed-cli
_filter_option_librespeed_cli() {
local line_input line_output column_count column_all_count
local file_input="$1" file_output="$2"
while IFS= read -r line_input; do
IFS="$old_IFS"
line_output=""
column_all_count="$(echo "$line_input" | awk '{ print NF }')"
for ((column_count = 1; column_count <= column_all_count; column_count++)); do
_filter_option_1_para --server-json --server-json
_filter_option_1_para --local-json --local-json
_filter_option_1_para --server --server
_filter_option_1_para --duration --duration
_filter_option_0_para --no-download --no-download
_filter_option_0_para --no-upload --no-upload
_filter_option_0_para --no-icmp --no-icmp
_filter_option_0_para -4 --ipv4
_filter_option_0_para -6 --ipv6
done
echo "$line_output" >>"$file_output"
done <"$file_input"
}
# iperf3
_filter_option_iperf3() {
local line_input line_output column_count column_all_count
local file_input="$1" file_output="$2"
while IFS= read -r line_input; do
IFS="$old_IFS"
line_output=""
column_all_count="$(echo "$line_input" | awk '{ print NF }')"
for ((column_count = 1; column_count <= column_all_count; column_count++)); do
_filter_option_1_para -c -c
_filter_option_1_para -P --parallel
_filter_option_1_para -i --interval
_filter_option_1_para -t --time
_filter_option_1_para -O --omit
_filter_option_0_para -R --reverse
_filter_option_0_para -u --udp
_filter_option_0_para -4 --version4
_filter_option_0_para -6 --version6
_filter_option_0_para --up-and-down --up-and-down
_filter_option_iperf3_1 -p --port
done
echo "$line_output" >>"$file_output"
done <"$file_input"
}
########## 检测选项,用于预判测速结果 ##########
_check_option() {
local option_input="$1" options_input="$2"
if echo "$options_input" | grep -q -- "$option_input"; then
return 0
else
return 1
fi
}
_check_num() {
local num_input="$1"
if [[ "$num_input" =~ ^[0-9]+(\.[0-9]+)?$ ]] && ! [[ "$num_input" =~ ^0+(\.0+)?$ ]]; then
return 0
else
return 1
fi
}
########## 输出 ##########
_check_output() {
local i_check_output
local count_check_output="0"
for i_check_output in $(echo "$download $upload $latency $jitter"); do
if [[ "$i_check_output" =~ 失败 ]]; then
count_check_output=$((count_check_output + 1))
elif [[ "$i_check_output" =~ 跳过 ]]; then
count_check_output=$((count_check_output + 1))
fi
done
[ "$count_check_output" -ne 4 ] && printf "${yellow}%-s${green}%-${download_c}s${cyan}%-${upload_c}s${blue}%-${latency_c}s${purple}%-${jitter_c}s${endc}\n" "$node_name" "$download" "$upload" "$latency" "$jitter"
}
########## 删除残余文件 ##########
_rm_dir() {
_print_banner_4
rm -rf "$work_dir"
exit 0
}
########## debug ##########
_debug() {
local debug_tar_name
if [[ "$debug_flag" -eq 1 ]]; then
{
echo "OS info:"
cat /etc/os-release
echo "Shell info:"
echo "$SHELL"
echo "User info:"
echo "$UID"
echo "Loc info:"
echo "$loc"
} >$work_dir/info.txt
debug_tar_name="sp-debug-$(TZ=Asia/Shanghai date +"%Y%m%d%H%M%S").tar"
touch $work_dir/1.json
tar -cf "$work_dir/$debug_tar_name" ${work_dir}/*.{json,txt}
printf "\n${red}%-s${endc}\n" "方便的话欢迎将到GitHub反馈下述结果:"
curl -X POST -s -Fc=@"$work_dir/$debug_tar_name" -Fn="${debug_tar_name%.*}" -Fe=90d 'https://pastebin.888853.xyz'
echo
fi
}
########## main ##########
_main() {
trap '{ kill ${bar_pid} 2>/dev/null; printf "\r"; _debug; _rm_dir; }' EXIT
_check_architecture
_constant
_print_banner_1
_check_user
_check_region
_check_package tar tar
_check_package curl curl
_check_package iperf3 iperf3
_check_package bc bc
_make_dir
_download_tar
_check_tar_sha256
_unzip_tar
clear
_get_node_list
_classify_node
clear
_print_banner_1
[ -s "$work_dir"/banner-custom.txt ] && _print_banner_2
_print_banner_3
[ -s "$work_dir"/speedtest-cli-node.txt ] && _speedtest_cli_test
[ -s "$work_dir"/bim-core-node.txt ] && _bim_core_test
[ -s "$work_dir"/speedtest-go-node.txt ] && _speedtest_go_test
[ -s "$work_dir"/librespeed-cli-node.txt ] && _librespeed_cli_test
[ -s "$work_dir"/iperf3-node.txt ] && _iperf3_test
}
####################
for arg in "$@"; do
if [[ "$arg" == "--debug" ]]; then
debug_flag="1"
fi
done
_main
📖 使用教程
Linux Bash 多功能自更新测速脚本,下载并校验多个测速工具后执行网络测速。
远程来源:https://raw.githubusercontent.com/i-abc/Speedtest/main/speedtest.sh
远程来源:https://raw.githubusercontent.com/i-abc/Speedtest/main/speedtest.sh
🧬 版本记录
当前版本:1.2.0
🟢 1.2.0
仅记录日志
通过远程链接自动导入生成初始版本,请在正式发布前再次核对脚本说明与安全风险。
💬 评论 (0)