-
-
Save patmandenver/fe5648c6faad8f49ef8dd705a509bb7f to your computer and use it in GitHub Desktop.
| #!/bin/bash | |
| # scp-speed-test.sh | |
| # | |
| # Usage: | |
| # ./scp-speed-test.sh user@hostname [test file size in MBs] | |
| # | |
| ############################################################# | |
| ssh_server=$1 | |
| test_file=".scp-test-file" | |
| # Optional: user specified test file size in MBs | |
| if test -z "$2" | |
| then | |
| # default size is 10MB | |
| test_size="10" | |
| else | |
| test_size=$2 | |
| fi | |
| # generate a file of all zeros | |
| echo "Generating $test_size MB test file..." | |
| dd if=/dev/zero of=$test_file bs=$(echo "$test_size*1024*1024" | bc) \ | |
| count=1 &> /dev/null | |
| # upload test | |
| echo "Testing upload to $ssh_server..." | |
| up_speed=$(scp -v $test_file $ssh_server:$test_file 2>&1 | \ | |
| grep "Bytes per second" | \ | |
| sed "s/^[^0-9]*\([0-9.]*\)[^0-9]*\([0-9.]*\).*$/\1/g") | |
| up_speed=$(echo "($up_speed/1000000)" | bc) | |
| # download test | |
| echo "Testing download from $ssh_server..." | |
| down_speed=$(scp -v $ssh_server:$test_file $test_file 2>&1 | \ | |
| grep "Bytes per second" | \ | |
| sed "s/^[^0-9]*\([0-9.]*\)[^0-9]*\([0-9.]*\).*$/\2/g") | |
| down_speed=$(echo "($down_speed/1000000)" | bc) | |
| # clean up | |
| echo "Removing test file on $ssh_server..." | |
| ssh $ssh_server "rm $test_file" | |
| echo "Removing test file locally..." | |
| rm $test_file | |
| # print result | |
| echo "" | |
| echo "Upload speed: $up_speed MBps" | |
| echo "Download speed: $down_speed MBps" |
Very helpful. Thank you.
Awesome, thanks a lot!
Thanks for this!
Should read:
echo "Upload speed: $up_speed MBps"
echo "Download speed: $down_speed MBps"
As we're measuring in bytes and not bits.
Very nice! Here is an addition:
If someone has Compression yes in their ~/.ssh/config, as I do, then scp will do compression by default and these numbers will be misinforming.
Add the following to every scp command, just in case, to force no compression, -o 'Compression no'.
Also, some connections might not be faster than a MBps, so you should let decimals count.
Replace /1000000)" | bc with /1000000.)" | bc -l
Also, some connections might not already be in acknowledged_hosts so you may want to add -o 'StrictHostKeyChecking no' to all the scp commands.
I added some features such as argument parsing, checking if the server is reachable, the option to skip the download speed test, and a destination folder. Here it is,
#!/bin/bash
test_file=".scp-test-file"
# usage function
function usage()
{
cat << HEREDOC
Usage: $progname --server=<ip address> [--test_size=<MB> --do_download=<0/1> --server_dir=<server side dir>]
optional arguments:
-h, --help show this help message and exit
HEREDOC
}
# initialize variables and defaults
progname=$(basename $0)
server=
server_dir=./
do_download=1
test_size=10
###
# all args
L=(server \
do_download \
test_size \
server_dir)
arg_parse_str="help"
for arg in "${L[@]}"; do
arg_parse_str=${arg_parse_str},${arg}:
done
#echo $arg_parse_str
OPTS=$(getopt -o "h" --long ${arg_parse_str} -n "$progname" -- "$@")
if [ $? != 0 ] ; then echo "Error in command line arguments." >&2 ; usage; exit 1 ; fi
eval set -- "$OPTS"
while true; do
# uncomment the next line to see how shift is working
# echo "\$1:\"$1\" \$2:\"$2\""
case "$1" in
-h | --help ) usage; exit; ;;
-- ) shift; break ;;
esac
found=
for arg in "${L[@]}"; do
if [ "$1" == "--$arg" ]; then
declare ${arg}="$2";
shift 2;
found=1
break
fi
done
if [ -z "$found" ]; then
break
fi
done
if [ -z "$server" ]
then
usage;
exit;
fi
#[[ -z $(nc -W 1 -w 10 $server 22 2>/dev/null) ]] && echo "$server unreachable" && exit 0
#if your nc complains about not having -i command line option then use the line above
[[ -z $(nc -i 1 -w 10 $server 22 2>/dev/null) ]] && echo "$server unreachable" && exit 0
# generate a file of all zeros
echo "Generating $test_size MB test file..."
dd if=/dev/zero of=$test_file bs=$(echo "$test_size*1024*1024" | bc) \
count=1 &> /dev/null
# upload test
echo "Testing upload to $server..."
up_speed=$(scp -v -o 'Compression no' -o 'StrictHostKeyChecking no' $test_file $server:$server_dir/$test_file 2>&1 | \
grep "Bytes per second" | \
sed "s/^[^0-9]*\([0-9.]*\)[^0-9]*\([0-9.]*\).*$/\1/g")
up_speed=$(echo "($up_speed/1000)" | bc)
echo "Upload speed: $up_speed KBps on $server"
if [ "$do_download" == "1" ]; then
# download test
echo "Testing download from $server..."
down_speed=$(scp -v -o 'Compression no' -o 'StrictHostKeyChecking no' $server:$server_dir/$test_file $test_file 2>&1 | \
grep "Bytes per second" | \
sed "s/^[^0-9]*\([0-9.]*\)[^0-9]*\([0-9.]*\).*$/\2/g")
down_speed=$(echo "($down_speed/1000)" | bc)
echo "Download speed: $down_speed KBps on $server"
fi
# clean up
echo "Removing test file, $server:$server_dir/$test_file..."
ssh $server "rm $server_dir/$test_file"
echo "Removing test file locally..."
rm $test_fileInstead of uploading files, why not use dd to send junk data?
Upload
dd if=/dev/zero bs=1M count=1024 status=progress \
| ssh -o Compression=no workspace "cat > /dev/null"
Download
ssh -o Compression=no workspace \
"dd if=/dev/zero bs=1M count=1024" \
| dd of=/dev/null bs=1M status=progress
Thanks)