Last active
July 1, 2024 20:36
-
-
Save silv3rr/572964d668bfe20ba4c5e9e304a63e8a to your computer and use it in GitHub Desktop.
Wrapper around speedtest-cli (uses speedtest.net)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Wrapper around speedtest cli (speedtest.net) | |
#################################################### | |
# - Required: https://www.speedtest.net/apps/cli or https://github.com/sivel/speedtest-cli | |
# - Put this script in same dir as speedtest-cli or in parent dir | |
# - Uncomment line below to add an extra exclude besides "-x" ('grep -v server/country') | |
#exclude="\(Vodafone\|Brazil\|Comcast\|Hawaii\)" | |
speedtest_bin="/usr/bin/speedtest" | |
#speedtest_bin="./test.sh" | |
func_exit () { | |
if [ -n "$speedtest_ip4" ] && [ -f "$speedtest_ip4" ]; then | |
rm -f "$speedtest_ip4" >/dev/null 2>&1 | |
fi | |
exit 0 | |
} | |
cli=0 | |
if echo "$speedtest_bin"|grep -Eq 'speedtest$'; then | |
cli=1 | |
elif echo "$speedtest_bin"|grep -Eq 'speedtest.py$'; then | |
cli=2 | |
# Try to locate required bin or .py script | |
else | |
if [ -z "$speedtest_bin" ]; then | |
scmd="$(command -v speedtest 2>&1)" | |
if [ -n "$scmd" ]; then | |
speedtest_bin="$scmd" | |
cli=1 | |
else | |
for i in . .. ../../src/speedtest-cli ../speedtest-cli speedtest-cli; do | |
if [ -x "$i/speedtest.py" ]; then | |
speedtest_bin="$i/speedtest.py" | |
cli=2 | |
break | |
fi | |
done | |
fi | |
fi | |
fi | |
if [ -z "$speedtest_bin" ]; then | |
printf "You need 'speedtest' or 'speedtest-cli':\n" | |
printf " - official cli: https://www.speedtest.net/apps/cli\n" | |
printf " - 3rd party: https://github.com/sivel/speedtest-cli\n" | |
printf " (git clone & chmod +x speedtest-cli/speedtest.py\n" | |
exit 1 | |
fi | |
if echo "$@" | grep -q '\-h'; then | |
printf "\nspeedtest cli wrapper (speedtest.net)\n" | |
printf "\nUsage : %s -[l|x] <Country|Server>\n" "$( basename "$0")" | |
printf "Options : [-l] to List servers\n" | |
printf " [-x] <pattern> to eXclude country/server\n" | |
printf " [-4] force ipv4 (speedtest-cli.py)\n" | |
printf " [-s] bind source <ip> (to speedtest)\n\n" | |
printf "Example : ./%s Romania\n\n" "$( basename "$0")" | |
printf "Press CTRL-C during speedtesting to abort\n\n" | |
exit 0 | |
fi | |
# Passtrough --ip and --source option | |
if echo "$@" | grep -q '\-s'; then | |
if [ "${cli:-0}" -eq 1 ]; then | |
source="--ip=" | |
elif [ "${cli:-0}" -eq 2 ]; then | |
source="--source " | |
fi | |
source+="$( echo "$@" | sed -E 's/.*(-s|--source) ?([0-9a-fA-F\.:]{4,}) ?.*/\2/' )" | |
fi | |
if echo "$@" | grep -q '\-x'; then | |
excl_argx="$( echo "$@" | sed -E 's/.*-x ?([^ ]+) ?.*/\1/' )" | |
grep_excl_argx="grep -Ev $excl_argx" | |
fi | |
if [ -n "$exclude" ]; then | |
grep_excl_var="grep -Ev $exclude" | |
fi | |
# Remove args except for Country | |
params="$( | |
echo "$@" | sed -E \ | |
-e 's/ ?(-l|--list|--servers|-4) ?//g' \ | |
-e 's/( ?-x ?[^ ]+ ?)(.*|$)/\2/' \ | |
-e 's/( ?(-s|--source) ?[0-9a-fA-F\.:]{4,} ?)(.*|$)/\3/' \ | |
)" | |
# Country specific excludes | |
case $params in | |
*AW*|*Aruba*) country_regex="(Aruba.*Italy)"; ;; | |
*ES*|*Spain*) country_regex="(Canarias|Lanzarote|Las Palmas|Mogan|Santa Cruz|Trinidad)"; ;; | |
*JE*|*Jersey*) country_regex="(Jersey.*United States)"; ;; | |
*GE*|*Georgia*) country_regex="(Georgia.*United States)"; ;; | |
*IN*|*India*) country_regex="(Indiara.*Brazil|Indianapolis.*United States)"; ;; | |
*ML*|*Mali*) country_regex="(Malik Cable.*New Delhi)"; ;; | |
*ME*|*Montenegro*) country_regex="(Montenegro.*Brazil)"; ;; | |
*MU*|*Mauritius*) country_regex="(Mauritius Telecom.*London)"; ;; | |
*NL*|*Netherlands*) country_regex="(Antilles|Curacao|St. Maarten|Saint Martin)"; ;; | |
*PE*|*Peru*) country_regex="(Telecom Italia.*Italy)"; ;; | |
*TR*|*Turkey*) country_regex="(Turkeynet.*Brazil)"; ;; | |
*UG*|*Uganda*) country_regex="(Uganda Hosting.*Germany|Uganda Hosting.*Finland)"; ;; | |
esac | |
if [ -n "$country_regex" ]; then | |
grep_excl_country="grep -Ev '$country_regex'" | |
fi | |
# Country code | |
if echo "$params" | grep -Eq "[A-Z]{2}"; then | |
ccode="$( echo "$params" | sed -E 's/.*([A-Z]{2}).*/\1/' )" | |
if command -v isoquery >/dev/null 2>&1; then | |
params="$(isoquery "$ccode" | awk -F'\t' '{ print $NF }')" | |
else | |
echo "To use ISO Country Codes install \"isoquery\", or use full Country Name instead" | |
exit 1 | |
fi | |
fi | |
if [ -z "$params" ]; then | |
printf "Specify country/server to result or speedtest, or try \"%s -h\"\n" "$(basename "$0")" | |
exit 1 | |
fi | |
if echo "$params" | grep -q "^-"; then | |
echo "Wrong argument(s)"; exit 1 | |
fi | |
# Modify Python code on the fly to force IPv4 (from: https://stackoverflow.com/a/50044152) | |
if echo "$@" | grep -q '\-4' && [ "${cli:-0}" -eq 2 ]; then | |
speedtest_ip4="/tmp/speedtest4.$$.py" | |
sed '/import socket/a\ | |
old_getaddrinfo = socket.getaddrinfo\ | |
def new_getaddrinfo(*args, **kwargs):\ | |
responses = old_getaddrinfo(*args, **kwargs)\ | |
return [response\ | |
for response in responses\ | |
if response[0] == socket.AF_INET]\ | |
socket.getaddrinfo = new_getaddrinfo'\ | |
"$speedtest_bin" >"$speedtest_ip4" && chmod +x "$speedtest_ip4" | |
speedtest_bin="$speedtest_ip4" | |
if [ -z "$speedtest_ip4" ] || [ ! -x "$speedtest_ip4" ]; then | |
printf "ERROR: could not force IPv4" | |
fi | |
fi | |
trap 'func_exit' HUP INT QUIT TERM | |
# Filter servers | |
for i in "grep \"$params\"" "$grep_excl_var" "$grep_excl_argx" "$grep_excl_country"; do | |
if [ -n "$i" ]; then | |
filter="$filter | $i" | |
fi | |
done && \ | |
filter="$( echo "$filter" | sed -E 's/^ ?\| //' )" | |
IFS="$IFS_SAVE" | |
IFS=$'\n' | |
snum=0 | |
if [ "${cli:-0}" -eq 1 ]; then | |
arg_list="--servers" | |
else | |
arg_list="--list" | |
fi | |
for i in $(eval "$speedtest_bin $arg_list | $filter"); do | |
result="$result $i _EOL_" | |
snum=$((snum+1)) | |
done | |
# List servers or run speedtest | |
printf "\nCountry/Server: %s\n" "$params" | |
printf "Excluding: %s %s %s\n\n" "$country_regex" "$excl_argx" "$exclude" | |
if { echo "$@" | grep -qi '\-l'; } then | |
for i in $( echo $result | sed 's/_EOL_/\n/g' ); do | |
echo "$i" | |
done | |
printf "\nTotal: %s servers\n\n" "$snum" | |
else | |
j=1 | |
if [ "${cli:-0}" -eq 1 ]; then | |
args="server-id=" | |
elif [ "${cli:-0}" -eq 2 ]; then | |
args="--secure --server " | |
awk_args="" | |
fi | |
for i in $( echo $result | sed 's/_EOL_/\n/g' | awk $awk_args '{ print $1 }' ); do | |
echo -n "Server ${j} of ${snum} -- " | |
$speedtest_bin $source ${args}${i} | |
echo | |
j=$((j+1)); | |
done | |
fi | |
IFS="$IFS_SAVE" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment