329 lines
13 KiB
Bash
Executable File
329 lines
13 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#########################################################################################################################################################################
|
|
# #
|
|
# 88 #
|
|
# 88 #
|
|
# 88 #
|
|
# ,adPPYba, 8b,dPPYba, ,adPPYba, 88 ,adPPYba, ,adPPYba, 88,dPYba,,adPYba, #
|
|
# I8[ "" 88P' `"8a a8P_____88 88 a8" "" a8" "8a 88P' "88" "8a #
|
|
# `"Y8ba, 88 88 8PP""""""" 88 8b 8b d8 88 88 88 #
|
|
# aa ]8I 88 88 "8b, ,aa 88 888 "8a, ,aa "8a, ,a8" 88 88 88 #
|
|
# `"YbbdP"' 88 88 `"Ybbd8"' 88 888 `"Ybbd8"' `"YbbdP"' 88 88 88 #
|
|
# #
|
|
# #
|
|
#########################################################################################################################################################################
|
|
# #
|
|
# Author: Snel.com - Yavuz Aydin #
|
|
# E-mail: support@snel.com #
|
|
# (c) Snel.com - all rights reserved #
|
|
# #
|
|
#########################################################################################################################################################################
|
|
# #
|
|
# Script: snench.sh #
|
|
# License: This file is licensed under the Apache License, Version 2.0 #
|
|
# Purpose: Easy and fast benchmarks! #
|
|
# Current version: https://git.snel.com/snelcom/snench #
|
|
# Usage: bash <(curl -s https://git.snel.com/snelcom/snench/raw/branch/master/snench.sh || wget -qO- https://git.snel.com/snelcom/snench/raw/branch/master/snench.sh) #
|
|
# #
|
|
#########################################################################################################################################################################
|
|
|
|
command_exists()
|
|
{
|
|
command -v "$@" > /dev/null 2>&1
|
|
}
|
|
|
|
Bps_to_MiBps()
|
|
{
|
|
awk '{ printf "%.2f MiB/s\n", $0 / 1024 / 1024 } END { if (NR == 0) { print "error" } }'
|
|
}
|
|
|
|
B_to_MiB()
|
|
{
|
|
awk '{ printf "%.0f MiB\n", $0 / 1024 / 1024 } END { if (NR == 0) { print "error" } }'
|
|
}
|
|
|
|
redact_ip()
|
|
{
|
|
case "$1" in
|
|
*.*)
|
|
printf '%s.xxxx\n' "$(printf '%s\n' "$1" | cut -d . -f 1-3)"
|
|
;;
|
|
*:*)
|
|
printf '%s:xxxx\n' "$(printf '%s\n' "$1" | cut -d : -f 1-3)"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
finish()
|
|
{
|
|
printf '\n'
|
|
rm -f test_$$
|
|
exit
|
|
}
|
|
# make sure the dd test file is always deleted, even when the script is
|
|
# interrupted while dd is running
|
|
trap finish EXIT INT TERM
|
|
|
|
command_benchmark()
|
|
{
|
|
if [ "$1" = "-q" ]
|
|
then
|
|
QUIET=1
|
|
shift
|
|
fi
|
|
|
|
if command_exists "$1"
|
|
then
|
|
( time "$gnu_dd" if=/dev/zero bs=1M count=500 2> /dev/null | \
|
|
"$@" > /dev/null ) 2>&1
|
|
else
|
|
if [ "$QUIET" -ne 1 ]
|
|
then
|
|
unset QUIET
|
|
printf '[command `%s` not found]\n' "$1"
|
|
fi
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
dd_benchmark()
|
|
{
|
|
# returns IO speed in B/s
|
|
|
|
# Temporarily override locale to deal with non-standard decimal separators
|
|
# (e.g. "," instead of ".").
|
|
# The awk script assumes bytes/second if the suffix is !~ [TGMK]B. Call me
|
|
# if your storage system does more than terabytes per second; I'll want to
|
|
# see that.
|
|
LC_ALL=C "$gnu_dd" if=/dev/zero of=test_$$ bs=64k count=16k conv=fdatasync 2>&1 | \
|
|
awk -F, '
|
|
{
|
|
io=$NF
|
|
}
|
|
END {
|
|
if (io ~ /TB\/s/) {printf("%.0f\n", 1000*1000*1000*1000*io)}
|
|
else if (io ~ /GB\/s/) {printf("%.0f\n", 1000*1000*1000*io)}
|
|
else if (io ~ /MB\/s/) {printf("%.0f\n", 1000*1000*io)}
|
|
else if (io ~ /KB\/s/) {printf("%.0f\n", 1000*io)}
|
|
else { printf("%.0f", 1*io)}
|
|
}'
|
|
rm -f test_$$
|
|
}
|
|
|
|
download_benchmark()
|
|
{
|
|
curl --max-time 10 -so /dev/null -w '%{speed_download}\n' "$@"
|
|
}
|
|
|
|
if ! command_exists curl
|
|
then
|
|
printf '%s\n' 'This script requires curl, but it could not be found.' 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
if command_exists gdd
|
|
then
|
|
gnu_dd='gdd'
|
|
elif command_exists dd
|
|
then
|
|
gnu_dd='dd'
|
|
else
|
|
printf '%s\n' 'This script requires dd, but it could not be found.' 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! "$gnu_dd" --version > /dev/null 2>&1
|
|
then
|
|
printf '%s\n' 'It seems your system only has a non-GNU version of dd.'
|
|
printf '%s\n' 'dd write tests disabled.'
|
|
gnu_dd=''
|
|
fi
|
|
|
|
printf '%s\n' '-------------------------------------------------'
|
|
printf ' snench.sh v2021.04.15 -- https://git.snel.com/snelcom/snench\n'
|
|
date -u '+ benchmark timestamp: %F %T UTC'
|
|
printf '%s\n' '-------------------------------------------------'
|
|
|
|
printf '\n'
|
|
|
|
if ! command_exists ioping
|
|
then
|
|
curl -s https://git.snel.com/snelcom/snench/raw/branch/master/ioping.static || wget -qO- https://git.snel.com/snelcom/snench/raw/branch/master/ioping.static
|
|
chmod +x ioping.static
|
|
ioping_cmd="./ioping.static"
|
|
else
|
|
ioping_cmd="ioping"
|
|
fi
|
|
|
|
# Basic info
|
|
if [ "$(uname)" = "Linux" ]
|
|
then
|
|
printf 'Processor: '
|
|
awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//'
|
|
printf 'CPU cores: '
|
|
awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo
|
|
printf 'Frequency: '
|
|
awk -F: ' /cpu MHz/ {freq=$2} END {print freq " MHz"}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//'
|
|
printf 'RAM: '
|
|
free -h | awk 'NR==2 {print $2}'
|
|
if [ "$(swapon -s | wc -l)" -lt 2 ]
|
|
then
|
|
printf 'Swap: -\n'
|
|
else
|
|
printf 'Swap: '
|
|
free -h | awk '/Swap/ {printf $2}'
|
|
printf '\n'
|
|
fi
|
|
else
|
|
# we'll assume FreeBSD, might work on other BSDs too
|
|
printf 'Processor: '
|
|
sysctl -n hw.model
|
|
printf 'CPU cores: '
|
|
sysctl -n hw.ncpu
|
|
printf 'Frequency: '
|
|
grep -Eo -- '[0-9.]+-MHz' /var/run/dmesg.boot | tr -- '-' ' ' | sort -u
|
|
printf 'RAM: '
|
|
sysctl -n hw.physmem | B_to_MiB
|
|
|
|
if [ "$(swapinfo | wc -l)" -lt 2 ]
|
|
then
|
|
printf 'Swap: -\n'
|
|
else
|
|
printf 'Swap: '
|
|
swapinfo -k | awk 'NR>1 && $1!="Total" {total+=$2} END {print total*1024}' | B_to_MiB
|
|
fi
|
|
fi
|
|
printf 'Kernel: '
|
|
uname -s -r -m
|
|
|
|
printf '\n'
|
|
|
|
printf 'Disks:\n'
|
|
if command_exists lsblk && [ -n "$(lsblk)" ]
|
|
then
|
|
lsblk --nodeps --noheadings --output NAME,SIZE,ROTA --exclude 1,2,11 | sort | awk '{if ($3 == 0) {$3="SSD"} else {$3="HDD"}; printf("%-3s%8s%5s\n", $1, $2, $3)}'
|
|
elif [ -r "/var/run/dmesg.boot" ]
|
|
then
|
|
awk '/(ad|ada|da|vtblk)[0-9]+: [0-9]+.B/ { print $1, $2/1024, "GiB" }' /var/run/dmesg.boot | sort -u
|
|
elif command_exists df
|
|
then
|
|
df -h --output=source,fstype,size,itotal | awk 'NR == 1 || /^\/dev/'
|
|
else
|
|
printf '[ no data available ]'
|
|
fi
|
|
|
|
printf '\n'
|
|
|
|
# CPU tests
|
|
export TIMEFORMAT='%3R seconds'
|
|
|
|
printf 'CPU: SHA256-hashing 500 MB\n '
|
|
command_benchmark -q sha256sum || command_benchmark -q sha256 || printf '[no SHA256 command found]\n'
|
|
|
|
printf 'CPU: bzip2-compressing 500 MB\n '
|
|
command_benchmark bzip2
|
|
|
|
printf 'CPU: AES-encrypting 500 MB\n '
|
|
command_benchmark openssl enc -e -aes-256-cbc -pass pass:12345678 | sed '/^\*\*\* WARNING : deprecated key derivation used\.$/d;/^Using -iter or -pbkdf2 would be better\.$/d'
|
|
|
|
printf '\n'
|
|
|
|
# ioping
|
|
printf 'ioping: seek rate\n '
|
|
"$ioping_cmd" -DR -w 5 . | tail -n 1
|
|
printf 'ioping: sequential read speed\n '
|
|
"$ioping_cmd" -DRL -w 5 . | tail -n 2 | head -n 1
|
|
|
|
printf '\n'
|
|
|
|
# dd disk test
|
|
printf 'dd: sequential write speed\n'
|
|
|
|
if [ -z "$gnu_dd" ]
|
|
then
|
|
printf ' %s\n' '[disabled due to missing GNU dd]'
|
|
else
|
|
io1=$( dd_benchmark )
|
|
printf ' 1st run: %s\n' "$(printf '%d\n' "$io1" | Bps_to_MiBps)"
|
|
|
|
io2=$( dd_benchmark )
|
|
printf ' 2nd run: %s\n' "$(printf '%d\n' "$io2" | Bps_to_MiBps)"
|
|
|
|
io3=$( dd_benchmark )
|
|
printf ' 3rd run: %s\n' "$(printf '%d\n' "$io3" | Bps_to_MiBps)"
|
|
|
|
# Calculating avg I/O (better approach with awk for non int values)
|
|
ioavg=$( awk 'BEGIN{printf("%.0f", ('"$io1"' + '"$io2"' + '"$io3"')/3)}' )
|
|
printf ' average: %s\n' "$(printf '%d\n' "$ioavg" | Bps_to_MiBps)"
|
|
fi
|
|
|
|
printf '\n'
|
|
|
|
# Network speedtests
|
|
|
|
ipv4=$(curl -4 -s --max-time 5 http://icanhazip.com/)
|
|
if [ -n "$ipv4" ]
|
|
then
|
|
printf 'IPv4 speedtests\n'
|
|
printf ' your IPv4: %s\n' "$(redact_ip "$ipv4")"
|
|
printf '\n'
|
|
|
|
printf ' Cachefly CDN: '
|
|
download_benchmark -4 http://cachefly.cachefly.net/100mb.test | \
|
|
Bps_to_MiBps
|
|
|
|
printf ' Leaseweb (NL): '
|
|
download_benchmark -4 http://mirror.nl.leaseweb.net/speedtest/100mb.bin | \
|
|
Bps_to_MiBps
|
|
|
|
printf ' Softlayer DAL (US): '
|
|
download_benchmark -4 http://speedtest.dal06.softlayer.com/downloads/test100.zip | \
|
|
Bps_to_MiBps
|
|
|
|
printf ' Online.net (FR): '
|
|
download_benchmark -4 http://ping.online.net/100Mo.dat | \
|
|
Bps_to_MiBps
|
|
|
|
printf ' OVH BHS (CA): '
|
|
download_benchmark -4 http://speedtest-bhs.as16276.ovh/files/100Mio.dat | \
|
|
Bps_to_MiBps
|
|
|
|
else
|
|
printf 'No IPv4 connectivity detected\n'
|
|
fi
|
|
|
|
printf '\n'
|
|
|
|
ipv6=$(curl -6 -s --max-time 5 http://icanhazip.com/)
|
|
if [ -n "$ipv6" ]
|
|
then
|
|
printf 'IPv6 speedtests\n'
|
|
printf ' your IPv6: %s\n' "$(redact_ip "$ipv6")"
|
|
printf '\n'
|
|
|
|
printf ' Leaseweb (NL): '
|
|
download_benchmark -6 http://mirror.nl.leaseweb.net/speedtest/100mb.bin | \
|
|
Bps_to_MiBps
|
|
|
|
printf ' Softlayer DAL (US): '
|
|
download_benchmark -6 http://speedtest.dal06.softlayer.com/downloads/test100.zip | \
|
|
Bps_to_MiBps
|
|
|
|
printf ' Online.net (FR): '
|
|
download_benchmark -6 http://ping6.online.net/100Mo.dat | \
|
|
Bps_to_MiBps
|
|
|
|
printf ' OVH BHS (CA): '
|
|
download_benchmark -6 http://speedtest-bhs.as16276.ovh/files/100Mio.dat | \
|
|
Bps_to_MiBps
|
|
|
|
else
|
|
printf 'No IPv6 connectivity detected\n'
|
|
fi
|
|
|
|
printf '%s\n' '-------------------------------------------------'
|
|
|
|
# delete downloaded ioping binary if script has been run straight from a pipe
|
|
# (rather than a downloaded file)
|
|
[ -t 0 ] || rm -f ioping.static
|