Skip to content

Instantly share code, notes, and snippets.

@mailinglists35
Created July 9, 2025 13:19
Show Gist options
  • Save mailinglists35/0d4e70328d3d81d2724cce0d676dcbc0 to your computer and use it in GitHub Desktop.
Save mailinglists35/0d4e70328d3d81d2724cce0d676dcbc0 to your computer and use it in GitHub Desktop.

Revisions

  1. mailinglists35 created this gist Jul 9, 2025.
    162 changes: 162 additions & 0 deletions net_rate_google_gemini.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,162 @@
    #!/bin/bash

    # Funcție pentru a afișa utilizarea și a ieși
    show_help() {
    echo "Utilizare: $0 [-i <interfață>] [-t <secunde>]"
    echo " -i <interfață> : Specifică interfața de rețea de monitorizat (ex: eth0, enp0s3)."
    echo " Dacă nu este specificată, se va detecta interfața implicită."
    echo " -t <secunde> : Intervalul de timp în secunde pentru calculul mediei și refresh (implicit: 1)."
    echo " Va afișa media ultimelor <secunde> și se va actualiza la fiecare <secunde>."
    echo ""
    echo "Exemple:"
    echo " $0 # Monitorizează interfața implicită la fiecare secundă"
    echo " $0 -i enp0s3 # Monitorizează enp0s3 la fiecare secundă"
    echo " $0 -t 5 # Monitorizează interfața implicită la fiecare 5 secunde"
    echo " $0 -i eth0 -t 10 # Monitorizează eth0 la fiecare 10 secunde"
    exit 0
    }

    # Valori implicite
    INTERFACE=""
    INTERVAL=1

    # Procesează argumentele din linia de comandă
    while getopts "i:t:h" opt; do
    case ${opt} in
    i ) INTERFACE=$OPTARG ;;
    t ) INTERVAL=$OPTARG ;;
    h ) show_help ;;
    \? ) echo "Opțiune invalidă: -$OPTARG" >&2; show_help ;;
    : ) echo "Opțiunea -$OPTARG necesită un argument." >&2; show_help ;;
    esac
    done

    # Verifică dacă INTERVAL este un număr valid
    if ! [[ "$INTERVAL" =~ ^[0-9]+$ ]] || [ "$INTERVAL" -eq 0 ]; then
    echo "Eroare: Intervalul de timp trebuie să fie un număr pozitiv."
    show_help
    fi

    # --- Funcție pentru a returna scriptul AWK de parsare a rutei ---
    get_awk_route_parser() {
    cat <<'EOF_AWK'
    {
    dev_name = ""; metric_val = "0"; # Initialize dev_name as empty, metric_val as 0 (default metric)
    for (i=1; i<=NF; i++) {
    if ($i == "dev") {
    dev_name = $(i+1);
    }
    if ($i == "metric") {
    metric_val = $(i+1);
    }
    }
    if (dev_name != "") { # Only dev_name is mandatory
    print dev_name " " metric_val;
    }
    }
    EOF_AWK
    }


    # Detectează interfața implicită dacă nu este specificată
    if [ -z "$INTERFACE" ]; then
    # Vom colecta toate rutele default găsite, împreună cu interfața și metricul
    # Format: "interfață metric"
    DEFAULT_ROUTES_CANDIDATES=""

    # Stochează scriptul AWK într-o variabilă
    AWK_SCRIPT_CONTENT=$(get_awk_route_parser)

    # 1. Caută ruta default în tabela 'main' (comportament normal)
    # Folosim ip route show (fara 'table main' explicit) pentru a acoperi cazurile in care main e implicita
    MAIN_DEFAULT=$(ip route show | awk '/^default/ { print | "cat" }' | awk "$AWK_SCRIPT_CONTENT")
    if [ -n "$MAIN_DEFAULT" ]; then
    DEFAULT_ROUTES_CANDIDATES="$MAIN_DEFAULT"
    fi

    # 2. Caută rute default în tabelele custom definite de ip rules
    CUSTOM_TABLES=$(ip rule | awk '{
    for (i=1; i<=NF; i++) {
    if ($i == "lookup" && $(i+1) !~ /^(local|main|default)$/) {
    print $(i+1);
    }
    }
    }' | sort -u) # Folosim sort -u pentru a evita duplicaturile

    for TABLE_NAME in $CUSTOM_TABLES; do
    TABLE_DEFAULT=$(ip route show table "$TABLE_NAME" | awk '/^default/ { print | "cat" }' | awk "$AWK_SCRIPT_CONTENT")
    if [ -n "$TABLE_DEFAULT" ]; then
    if [ -n "$DEFAULT_ROUTES_CANDIDATES" ]; then
    DEFAULT_ROUTES_CANDIDATES="${DEFAULT_ROUTES_CANDIDATES}\n${TABLE_DEFAULT}"
    else
    DEFAULT_ROUTES_CANDIDATES="$TABLE_DEFAULT"
    fi
    fi
    done

    # Acum că avem toți candidații, sortează-i după metric și ia-l pe cel cu metricul cel mai mic
    if [ -n "$DEFAULT_ROUTES_CANDIDATES" ]; then
    INTERFACE=$(echo -e "$DEFAULT_ROUTES_CANDIDATES" | sort -nk2 | head -n1 | awk '{print $1}')
    fi

    if [ -z "$INTERFACE" ]; then
    echo "Eroare: Nu s-a putut detecta o interfață implicită."
    echo "Vă rugăm să specificați una folosind -i <interfață>."
    exit 1
    fi
    echo "Interfață implicită detectată: $INTERFACE"
    fi

    # Verifică dacă interfața există
    if ! ip link show "$INTERFACE" &> /dev/null; then
    echo "Eroare: Interfața '$INTERFACE' nu există sau nu este activă."
    exit 1
    fi

    echo "Monitorizare interfață: $INTERFACE | Interval: $INTERVAL secunde"
    echo "---------------------------------------------------------------"
    echo " Rx (KB/s) | Tx (KB/s) | Total (KB/s)"
    echo "---------------------------------------------------------------"

    # Inițializarea valorilor anterioare
    PREV_RX_BYTES=$(cat "/sys/class/net/$INTERFACE/statistics/rx_bytes")
    PREV_TX_BYTES=$(cat "/sys/class/net/$INTERFACE/statistics/tx_bytes")
    LAST_TIMESTAMP=$(date +%s)

    while true; do
    sleep "$INTERVAL"

    CURRENT_RX_BYTES=$(cat "/sys/class/net/$INTERFACE/statistics/rx_bytes")
    CURRENT_TX_BYTES=$(cat "/sys/class/net/$INTERFACE/statistics/tx_bytes")
    CURRENT_TIMESTAMP=$(date +%s)

    TIME_DIFF=$((CURRENT_TIMESTAMP - LAST_TIMESTAMP))

    # Prevenim împărțirea la zero și resetăm dacă intervalul este prea mic sau negativ (nu ar trebui)
    if [ "$TIME_DIFF" -le 0 ]; then
    PREV_RX_BYTES=$CURRENT_RX_BYTES
    PREV_TX_BYTES=$CURRENT_TX_BYTES
    LAST_TIMESTAMP=$CURRENT_TIMESTAMP
    continue
    fi

    # Calculează ratele în bytes/secundă
    RX_RATE_BPS=$(( (CURRENT_RX_BYTES - PREV_RX_BYTES) / TIME_DIFF ))
    TX_RATE_BPS=$(( (CURRENT_TX_BYTES - PREV_TX_BYTES) / TIME_DIFF ))

    # !!! Modificare AICI: Forțează locales pentru calcule și printf !!!
    # Convertește în KB/secundă (rotunjire la 2 zecimale cu printf)
    # Folosim bash arithmetic pentru a calcula valorile intregi pentru a minimiza dependintele,
    # apoi bc pentru float.
    RX_RATE_KBPS=$(LC_NUMERIC=C bc -l <<< "scale=2; $RX_RATE_BPS / 1024")
    TX_RATE_KBPS=$(LC_NUMERIC=C bc -l <<< "scale=2; $TX_RATE_BPS / 1024")
    TOTAL_RATE_KBPS=$(LC_NUMERIC=C bc -l <<< "scale=2; ($RX_RATE_BPS + $TX_RATE_BPS) / 1024")

    # Afișează rezultatele formatat
    LC_NUMERIC=C printf "%10.2f | %11.2f | %12.2f\n" "$RX_RATE_KBPS" "$TX_RATE_KBPS" "$TOTAL_RATE_KBPS"

    # Actualizează valorile anterioare pentru următoarea iterație
    PREV_RX_BYTES=$CURRENT_RX_BYTES
    PREV_TX_BYTES=$CURRENT_TX_BYTES
    LAST_TIMESTAMP=$CURRENT_TIMESTAMP
    done