Skip to content

Instantly share code, notes, and snippets.

@koter84
Last active August 8, 2024 14:01
Show Gist options
  • Save koter84/e30c6cfdf2d134562085 to your computer and use it in GitHub Desktop.
Save koter84/e30c6cfdf2d134562085 to your computer and use it in GitHub Desktop.
Run a lot of pings in parallel
#!/bin/bash
############################
## Methods
############################
prefix_to_bit_netmask() {
prefix=$1;
shift=$(( 32 - prefix ));
bitmask=""
for (( i=0; i < 32; i++ )); do
num=0
if [ $i -lt $prefix ]; then
num=1
fi
space=
if [ $(( i % 8 )) -eq 0 ]; then
space=" ";
fi
bitmask="${bitmask}${space}${num}"
done
echo $bitmask
}
bit_netmask_to_wildcard_netmask() {
bitmask=$1;
wildcard_mask=
for octet in $bitmask; do
wildcard_mask="${wildcard_mask} $(( 255 - 2#$octet ))"
done
echo $wildcard_mask;
}
#######################
## MAIN
#######################
lines=$@
for ip in ${lines[@]}; do
net=$(echo $ip | cut -d '/' -f 1);
prefix=$(echo $ip | cut -d '/' -f 2);
bit_netmask=$(prefix_to_bit_netmask $prefix);
wildcard_mask=$(bit_netmask_to_wildcard_netmask "$bit_netmask");
str=
for (( i = 1; i <= 4; i++ )); do
range=$(echo $net | cut -d '.' -f $i)
mask_octet=$(echo $wildcard_mask | cut -d ' ' -f $i)
if [ $mask_octet -gt 0 ]; then
range="{$range..$(( $range | $mask_octet ))}";
fi
str="${str} $range"
done
ips=$(echo $str | sed "s, ,\\.,g"); ## replace spaces with periods, a join...
eval echo $ips
done
#!/bin/bash
log_file=$(mktemp "/tmp/pingchecker_XXXXX.log")
function catch_exit()
{
if [ -f ${log_file} ]
then
rm ${log_file}
fi
}
trap catch_exit EXIT
## array maken met alle te checken servers...
if [ "$#" -eq 0 ]
then
echo "No IPs given as arguments..."
exit
else
servers=("$@")
for element in $(seq 0 $((${#servers[@]} - 1)))
do
cur="${servers[$element]}"
## -h || --help : show help
if [ "$cur" == "-h" ] || [ "$cur" == "--help" ]
then
echo "options:"
echo " -h|--help this help message"
echo " -q|-s only give number of OK/NOK (summary)"
echo " --OK-count only give number of OK"
echo " --OK|-OK only list pingable IP's"
echo " --slow wait 0.01s between pings"
exit
fi
## -q || -s : only give nr OK/NOK
if [ "$cur" == "-q" ] || [ "$cur" == "-s" ]
then
quiet="TRUE"
unset servers[$element]
fi
## --OK : only return a list of pingable ip's
if [ "$cur" == "--OK" ] || [ "$cur" == "-OK" ]
then
quiet="TRUE"
only_OK="TRUE"
unset servers[$element]
fi
## --OK-count : only return a list of pingable ip's
if [ "$cur" == "--OK-count" ]
then
quiet="TRUE"
only_OK_count="TRUE"
unset servers[$element]
fi
# --slow : wait 0.01s between pings
if [ "$cur" == "--slow" ]
then
slow="TRUE"
unset servers[$element]
fi
done
## reindex the array
servers=("${servers[@]}")
fi
## ----------------------------------------- ##
if [ "${quiet}" != "TRUE" ]
then
echo "Ping Checker [ $(date --rfc-3339=seconds) ]"
fi
function getHostPing
{
hostname=$1
cur_name=`printf "%-19s" $hostname`
result=$(ping -c1 -w15 $hostname)
result_status=$?
if [ "$result_status" == "0" ]; then
echo "$cur_name (OK)" >> $log_file
else
echo "$cur_name (NOK)" >> $log_file
fi
}
echo -n "" > $log_file
for element in $(seq 0 $((${#servers[@]} - 1)))
do
cur="${servers[$element]}"
if [[ $cur == */* ]]; then
for curr in $(./__cidr-to-ip.sh "$cur"); do
getHostPing $curr &
let i++
if [ "${slow}" == "TRUE" ]
then
sleep 0.01
fi
done
else
getHostPing $cur &
let i++
if [ "${slow}" == "TRUE" ]
then
sleep 0.01
fi
fi
done
if [ "${quiet}" != "TRUE" ]
then
echo "totaal aantal: $i"
fi
while true
do
lines=$(wc -l $log_file|cut -d" " -f1)
if [ "$lines" != "$oldlines" ]
then
if [ "${quiet}" != "TRUE" ]
then
echo -n "$lines"
fi
oldlines=$lines
fi
if [ "$lines" == "$i" ]
then
if [ "${quiet}" != "TRUE" ]
then
echo ""
fi
break
fi
let try++
if [ "$try" -gt "70" ]
then
if [ "${quiet}" != "TRUE" ]
then
echo "FAIL"
fi
break
fi
if [ "${quiet}" != "TRUE" ]
then
echo -n "."
fi
if [ "$try" -gt "60" ]; then
if [ "${slow}" == "TRUE" ]
then
sleep 3.0
else
sleep 1.0
fi
elif [ "$try" -gt "50" ]; then
sleep 0.8
elif [ "$try" -gt "40" ]; then
sleep 0.4
elif [ "$try" -gt "30" ]; then
sleep 0.2
elif [ "$try" -gt "20" ]; then
sleep 0.1
else
sleep 0.02
fi
done
if [ "${quiet}" != "TRUE" ]
then
tail -n$i $log_file | sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n
fi
if [ "${only_OK}" == "TRUE" ]
then
tail -n$i $log_file | sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n | grep '(OK)' | awk '{ printf $1 " " }'
fi
if [ "${only_OK_count}" == "TRUE" ]
then
tail -n$i $log_file | sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n | grep '(OK)' | wc -l
fi
for element in $(seq 0 $((${#servers[@]} - 1)))
do
cur="${servers[$element]}"
# check $cur in $log_file
if [[ $cur == */* ]]; then
for curr in $(./__cidr-to-ip.sh "$cur"); do
if [ "$(cat $log_file|grep $curr)" == "" ]; then
cur_name=`printf "%-19s" $curr`
echo "x $cur_name failed"
fi
done
else
if [ "$(cat $log_file|grep $cur)" == "" ]; then
cur_name=`printf "%-19s" $cur`
echo "y $cur_name failed"
fi
fi
done
if [ "$quiet" != "TRUE" ]
then
echo ""
fi
if [ "${only_OK}" != "TRUE" ] && [ "${only_OK_count}" != "TRUE" ]
then
if [ "$(cat $log_file|grep '(OK)'|wc -l)" != "0" ]; then
echo "(OK) $(cat $log_file|grep '(OK)'|wc -l)"
fi
if [ "$(cat $log_file|grep '(NOK)'|wc -l)" != "0" ]; then
echo "(NOK) $(cat $log_file|grep '(NOK)'|wc -l)"
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment