Network Monitor Tool
This tool measures the network speed in real time and saves the maximum value in a separate column and prints it in a nice interface.

Save this file as wbw.sh and execute it and see the perfect monitor tool writtein in pure bash
#!/usr/bin/env bash
# - iNFO --------------------------------------
#
# Author: wuseman <wuseman@nr1.nu>
# FileName: wbw.sh
# Created: 2023-07-27 (19:47:47)
# Modified: 2026-03-18 (05:51:32)
# Version: 1.0
# License: WFTPL
#
# iRC: wuseman (Libera/EFnet/LinkNet)
# GitHub: https://github.com/wuseman/
#
# ---------------------------------------------
function show_header() {
local i_w=16 d_w=16 dm_w=16 u_w=15 um_w=15
# ASCII Separator
divider=$(printf "+ %-${i_w}s + %-${d_w}s + %-${dm_w}s + %-${u_w}s + %-${um_w}s +\n" " " " " " " " " " ")
divider="${divider// /-}"
# ASCII Footer
footer=$(printf "|_%-${i_w}s_|_%-${d_w}s_|_%-${dm_w}s_|_%-${u_w}s_|_%-${um_w}s_|\n" " " " " " " " " " ")
footer="${footer// /_}"
echo "$divider"
printf "| %-16s | %-16s | %-16s | %-15s | %-15s |\n" "Interface" "Download" "Download Max" "Upload" "Upload Max"
echo "$divider"
}
function get_bytes() {
local iface=$1
read -r _ rec _ _ _ _ _ _ _ trans _ < <(grep "$iface:" /proc/net/dev)
received_bytes=${rec#*:}
transmitted_bytes=$trans
}
function get_velocity() {
local value=$1 old_value=$2 time_diff=$3
if (($(bc <<< "$time_diff < 0.1"))); then
printf "0.00 MB/s"
return
fi
local vel=$(bc <<< "scale=2; ($value - $old_value) / 1048576 / $time_diff")
printf "%.2f MB/s" "$vel"
}
function get_max() {
local new_raw=$(echo "$1" | grep -oP "\d*\.?\d+")
local old_raw=$(echo "$2" | grep -oP "\d*\.?\d+")
[[ -z "$old_raw" ]] && old_raw="0.00"
if (($(bc -l <<< "$new_raw > $old_raw"))); then
printf "%.2f MB/s" "$new_raw"
else
printf "%.2f MB/s" "$old_raw"
fi
}
interfaces=()
while getopts ":i:a" opt; do
case $opt in
i) interfaces+=("$OPTARG") ;;
a) while read -r l; do
iface=$(echo "$l" | cut -d: -f1 | xargs)
[[ -n "$iface" ]] && interfaces+=("$iface")
done < <(tail -n +3 /proc/net/dev) ;;
esac
done
[[ ${#interfaces[@]} -eq 0 ]] && exit 1
declare -A old_recv_map old_trans_map max_dl_map max_ul_map
for iface in "${interfaces[@]}"; do
get_bytes "$iface"
old_recv_map[$iface]=$received_bytes
old_trans_map[$iface]=$transmitted_bytes
max_dl_map[$iface]="0.00 MB/s"
max_ul_map[$iface]="0.00 MB/s"
done
show_header
last_time=$(date +%s.%N)
first_run=1
tput civis
trap 'tput cnorm; echo; exit' INT TERM
while true; do
current_time=$(date +%s.%N)
delta_t=$(bc <<< "$current_time - $last_time")
last_time=$current_time
# If not first run, move up: Interface lines + 1 (footer)
if [[ $first_run -eq 0 ]]; then
tput cuu $((${#interfaces[@]} + 1))
fi
for iface in "${interfaces[@]}"; do
get_bytes "$iface"
v_rec=$(get_velocity "$received_bytes" "${old_recv_map[$iface]}" "$delta_t")
v_tra=$(get_velocity "$transmitted_bytes" "${old_trans_map[$iface]}" "$delta_t")
m_dl=$(get_max "$v_rec" "${max_dl_map[$iface]}")
m_ul=$(get_max "$v_tra" "${max_ul_map[$iface]}")
# Clear line and print data
printf "\r\033[K| \e[1m%-16s\e[0m | \e[1;31m↓\e[0m %-14s | \e[1;34m%-16s\e[0m | \e[1;32m↑\e[0m %-13s | \e[1;34m%-15s\e[0m |\n" \
"$iface" "$v_rec" "$m_dl" "$v_tra" "$m_ul"
old_recv_map[$iface]=$received_bytes
old_trans_map[$iface]=$transmitted_bytes
max_dl_map[$iface]=$m_dl
max_ul_map[$iface]=$m_ul
done
# Print footer with a newline and clear trailing artifacts
printf "\r\033[K%s\n" "$footer"
first_run=0
sleep 1
done
License
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.