Pages

find fastest mirror

#!/bin/bash
# ffmirror.sh
# find fastest mirror (?!?)
# give it a list of hosts and it will sort them
# according to their response time
# no switches (ATM) just ./ffmirror<mirrors.txt
# www.foo.org or http://www.foo.org or
# http://foo.org/page or ...

trap 'printf "\ncaught signal\nGot only ${#slist[@]}\n" &&
printf "%s\n" "${slist[@]}" && exit 1' 2

while read line; do
# get host & page
line=${line/[hH][tT][tT][pP]:\/\//}
[ "${line#*\/}" == "$line" ] && page="/" || page="/${line#*\/}"
host="${line%%\/*}"

# b-a to get time difference.
# could have used date +%s%N
# I guess this won't work on a BSD
a=$(</proc/uptime)
a=${a%%\ *}
a=${a/./}

# connect to host
exec 2>/dev/null 3<>/dev/tcp/$host/80 &&
# send a GET request and read 1st line of response
printf "GET $page HTTP/1.1\r\nHost: $host\r\n\r\n">&3 &&
read -u 3 -t 2 -a response &&  exec 3>&- &&
b=$(</proc/uptime) &&
b=${b%%\ *} &&
b=${b/./} ||
echo "$(date '+%m/%d/%Y %H:%M:%S') $host" >&2

# try next if not connected within 2s
[ $((b-a)) -lt 0 ] && continue

# this is my lazy sort algorithm (c)
c=$(((b-a)*100))
until [ "${slist[$c]}" == "" ]; do
((c++))
done
slist[$c]="$((b-a))0ms http://$host$page"

exec 3>&-

done

printf "%s\n" "${slist[@]}"



ex.

[grulos@slackd ~]$ cat s1.txt
www.shakakalasfdksasdfasdf.com
www.oooooooos.com
www.tttttttttt.org
www.google.com
www.kernel.org
www.linux.org
www.microsoft.com
www.slackware.org
www.freebsd.org
www.openbsd.org
www.netbsd.org
www.yahoo.com
www.wikipedia.org
www.w3.org
www.altavista.com
www.debian.org
www.gentoo.org
www.redhat.com
www.ibm.com
www.dell.com
[grulos@slackd ~]$ ./ffmirror.sh <s1.txt 2>>err.log
210ms http://www.wikipedia.org/
320ms http://www.debian.org/
350ms http://www.yahoo.com/
430ms http://www.w3.org/
510ms http://www.google.com/
560ms http://www.altavista.com/
630ms http://www.kernel.org/
690ms http://www.microsoft.com/
720ms http://www.openbsd.org/
740ms http://www.linux.org/
810ms http://www.freebsd.org/
820ms http://www.gentoo.org/
880ms http://www.netbsd.org/
890ms http://www.slackware.org/
930ms http://www.redhat.com/
1030ms http://www.dell.com/
1170ms http://www.ibm.com/
[grulos@slackd ~]$ cat err.log
04/04/2008 04:08:59 www.shakakalasfdksasdfasdf.com
04/04/2008 04:08:59 www.oooooooos.com
04/04/2008 04:09:00 www.tttttttttt.org
[grulos@slackd ~]$

3 comments:

alwaysbrowse said...

Thanks for developing this great script!!
I found your "find fastest mirror" code on the ubuntu forum. I am wondering if you could help me modify it a little bit. I would like to have the script executed by CRON every hour, so I need it to write the results to a file. It would be really great if the error messages (bad file name, connect timeout,etc) where written to a separate file / syslog or if it is easier to implement just ignored. Is there a way for it to not strip the http:// from the results? Please feel free to point me to someone else's work if you have found a better script. Regards, William

o foufoutos said...

Hey there..
I modified the script so all you need to do is redirect stderr to a file as shown in the example.
If you want to write to syslog check the man page for `logger'

l-arginine said...

I kept on jumbling the script, im thinking it might give me a different result.