Created
July 9, 2025 13:19
-
-
Save mailinglists35/0d4e70328d3d81d2724cce0d676dcbc0 to your computer and use it in GitHub Desktop.
linux any interface traffic rate viewer using only bare tools
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment