Skip to content

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.

Screenshot


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.