分類
Linux

在 Xfce 的狀態欄顯示網速

理想情況下,如果要在 Xfce 的狀態欄(Panel)顯示網速,只需要在狀態欄新增項目,選擇自帶的 Network Monitor 就可以了。但是某次升級內核後(5.14.0),/proc/net/dev 就不在有網速數據,導致從那裏讀取網速的 Network Monitor 和 vnstat 都無法工作。vnstat 可以統計過往流量的數據,不過也可以在路由器上查看,所以就先不管了。狀態欄的實時網速則可以通過下面的 Python 腳本來顯示。

#安裝依賴
sudo dnf install xfce4-genmon-plugin python3-gobject gtk3
#測試依賴
/usr/bin/python3 -c "import gi; print('PyGObject OK')"
#確認網絡數據
ethtool -S wlp1s0 | grep -E 'rx_bytes|tx_bytes'

#新建腳本目錄
mkdir -p ~/.local/bin ~/.cache/wifi-netload
nano ~/.local/bin/wifi-netload.py
#!/usr/bin/python3

import os
import re
import time
import subprocess

INTERFACE = "wlp1s0"

CACHE_DIR = os.path.expanduser("~/.cache/wifi-netload")
CACHE_FILE = os.path.join(CACHE_DIR, "counters")

os.makedirs(CACHE_DIR, exist_ok=True)


def get_counters():
    try:
        result = subprocess.run(
            ["/usr/sbin/ethtool", "-S", INTERFACE],
            capture_output=True,
            text=True,
            timeout=2,
            check=True,
        )

        rx_match = re.search(
            r"^\s*rx_bytes:\s*(\d+)",
            result.stdout,
            re.MULTILINE,
        )

        tx_match = re.search(
            r"^\s*tx_bytes:\s*(\d+)",
            result.stdout,
            re.MULTILINE,
        )

        if not rx_match or not tx_match:
            return None

        return int(rx_match.group(1)), int(tx_match.group(1))

    except (subprocess.SubprocessError, OSError, ValueError):
        return None


def format_rate(bytes_per_second):
    """Format speed using fixed-width decimal units."""

    kb = bytes_per_second / 1000

    if kb < 1000:
        return f"{kb:6.1f} K"

    mb = kb / 1000
    return f"{mb:6.2f} M"


def load_previous():
    try:
        with open(CACHE_FILE, "r") as f:
            parts = f.read().split()

        if len(parts) != 3:
            return None

        return (
            int(parts[0]),
            int(parts[1]),
            float(parts[2]),
        )

    except (OSError, ValueError):
        return None


def save_current(rx, tx):
    try:
        tmp = CACHE_FILE + ".tmp"

        with open(tmp, "w") as f:
            f.write(f"{rx} {tx} {time.monotonic()}\n")

        os.replace(tmp, CACHE_FILE)

    except OSError:
        pass


def main():
    current = get_counters()

    if current is None:
        print("0.0 KB/s  0.0 KB/s")
        return

    rx, tx = current
    previous = load_previous()

    save_current(rx, tx)

    if previous is None:
        print("0.0 KB/s  0.0 KB/s")
        return

    old_rx, old_tx, old_time = previous

    elapsed = time.monotonic() - old_time

    if elapsed <= 0:
        print("0.0 KB/s  0.0 KB/s")
        return

    # Handle counter resets.
    rx_delta = max(0, rx - old_rx)
    tx_delta = max(0, tx - old_tx)

    rx_rate = rx_delta / elapsed
    tx_rate = tx_delta / elapsed

    print(
        f"{format_rate(rx_rate)} "
        f"{format_rate(tx_rate)}"
    )


if __name__ == "__main__":
    main()

chmod +x ~/.local/bin/wifi-netload.py
#手動執行
~/.local/bin/wifi-netload.py
#應該顯示出類似   1.55 M   24.2 K

最後在 Xfce 狀態欄添加項目,選擇 Generic Monitor。命令欄填 /home/42/.local/bin/wifi-netload.py, 刷新頻率選 1,字體需要選一個等寬字體,不然網絡變動時會一跳一跳的,比如 Source Code Pro Bold 10。這樣就又能在狀態欄看見實時網速了。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *