#!/bin/bash # Emits {"rx":,"tx":,"iface":""} — network throughput # since the previous invocation, cached in a state file, so this script must # be polled periodically rather than run once. set -uo pipefail STATE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/omaspeedmeter" STATE_FILE="$STATE_DIR/net" mkdir -p -m 700 "$STATE_DIR" IFACE="auto" while (($# > 0)); do case "$1" in --iface) IFACE="${2:-auto}" shift 2 ;; *) shift ;; esac done now=$(date +%s.%N) prev_ts="" prev_rx=0 prev_tx=0 if [[ -f "$STATE_FILE" ]]; then while IFS='=' read -r key value; do case "$key" in prev_ts) [[ "$value" =~ ^[0-9]+(\.[0-9]+)?$ ]] && prev_ts="$value" ;; prev_rx) [[ "$value" =~ ^[0-9]+$ ]] && prev_rx="$value" ;; prev_tx) [[ "$value" =~ ^[0-9]+$ ]] && prev_tx="$value" ;; esac done <"$STATE_FILE" fi iface="$IFACE" if [[ "$iface" == "auto" || -z "$iface" ]]; then iface=$(ip route show default 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="dev") {print $(i+1); exit}}') fi rx=0 tx=0 if [[ -n "$iface" && -r "/sys/class/net/$iface/statistics/rx_bytes" ]]; then rx=$(<"/sys/class/net/$iface/statistics/rx_bytes") tx=$(<"/sys/class/net/$iface/statistics/tx_bytes") fi rx_rate=0 tx_rate=0 if [[ -n "$prev_ts" ]]; then dt=$(awk -v a="$now" -v b="$prev_ts" 'BEGIN { d=a-b; if (d<=0) d=1; printf "%.3f", d }') if ((rx >= prev_rx)); then rx_rate=$(awk -v d="$((rx - prev_rx))" -v dt="$dt" 'BEGIN { printf "%.0f", d/dt }') fi if ((tx >= prev_tx)); then tx_rate=$(awk -v d="$((tx - prev_tx))" -v dt="$dt" 'BEGIN { printf "%.0f", d/dt }') fi fi tmp_file=$(mktemp "$STATE_DIR/net.XXXXXX") { echo "prev_ts=$now" echo "prev_rx=$rx" echo "prev_tx=$tx" } >"$tmp_file" mv -f "$tmp_file" "$STATE_FILE" printf '{"rx":%s,"tx":%s,"iface":"%s"}\n' "$rx_rate" "$tx_rate" "$iface"