chore: updated wifi status script
0e9f5de5
1 file(s) · +66 −16
| 1 | 1 | #!/bin/sh |
|
| 2 | 2 | # Requires: iw |
|
| 3 | - | # Prints the wireless link state with a Nerd Font icon, for the status bar |
|
| 4 | - | # and menus. The icon tracks signal strength while connected, so it moves |
|
| 5 | - | # as the link does. |
|
| 6 | - | # Usage: wifi-status [-p|--plain] [IFACE] (default: first wireless interface) |
|
| 3 | + | # Prints the link state with a Nerd Font icon, for the status bar and menus. |
|
| 4 | + | # Wireless is the subject: the icon tracks signal strength while connected, |
|
| 5 | + | # so it moves as the link does. When wifi is not carrying traffic it falls |
|
| 6 | + | # back to reporting a live wired link rather than saying "off" while the |
|
| 7 | + | # machine is plainly online. |
|
| 8 | + | # Usage: wifi-status [-p|--plain] [-w|--wifi-only] [IFACE] |
|
| 9 | + | # -p plain output, no Nerd Font icon (for terminals without one) |
|
| 10 | + | # -w never fall back to wired, even with no wifi |
|
| 11 | + | # IFACE wireless interface to report (default: the first one the kernel |
|
| 12 | + | # lists); naming one implies -w, since the question was about it |
|
| 7 | 13 | set -u |
|
| 8 | 14 | ||
| 9 | 15 | PLAIN=0 |
|
| 10 | - | case "${1:-}" in |
|
| 11 | - | -p|--plain) PLAIN=1; shift ;; |
|
| 12 | - | esac |
|
| 16 | + | WIFI_ONLY=0 |
|
| 17 | + | ||
| 18 | + | while [ $# -gt 0 ]; do |
|
| 19 | + | case "$1" in |
|
| 20 | + | -p|--plain) PLAIN=1 ;; |
|
| 21 | + | -w|--wifi-only) WIFI_ONLY=1 ;; |
|
| 22 | + | -*) echo "usage: wifi-status [-p] [-w] [IFACE]" >&2; exit 2 ;; |
|
| 23 | + | *) break ;; |
|
| 24 | + | esac |
|
| 25 | + | shift |
|
| 26 | + | done |
|
| 13 | 27 | ||
| 14 | - | # ICON_ONLY/no-icon output goes through this so every exit path is consistent. |
|
| 28 | + | # Every exit path prints through this, so -p only has to be handled once. |
|
| 15 | 29 | say() { |
|
| 16 | 30 | if [ "$PLAIN" -eq 1 ]; then |
|
| 17 | 31 | echo "$2" |
|
| 20 | 34 | fi |
|
| 21 | 35 | } |
|
| 22 | 36 | ||
| 23 | - | # Ask the kernel which interfaces are wireless rather than assuming wlan0. |
|
| 24 | - | IFACE="${1:-$(iw dev 2>/dev/null | awk '$1 == "Interface" { print $2; exit }')}" |
|
| 37 | + | # A wired interface counts only if it is a real NIC (a `device` symlink rules |
|
| 38 | + | # out docker0, tailscale0 and the veths), is up, and holds a v4 address — |
|
| 39 | + | # that last part is what says it can actually carry traffic. |
|
| 40 | + | wired_iface() { |
|
| 41 | + | for path in /sys/class/net/*; do |
|
| 42 | + | iface=${path##*/} |
|
| 43 | + | [ "$iface" = "lo" ] && continue |
|
| 44 | + | [ -d "$path/wireless" ] || [ -e "$path/phy80211" ] && continue |
|
| 45 | + | [ -e "$path/device" ] || continue |
|
| 46 | + | [ "$(cat "$path/operstate" 2>/dev/null)" = "up" ] || continue |
|
| 47 | + | ip addr show "$iface" 2>/dev/null | grep -q "inet " || continue |
|
| 48 | + | echo "$iface" |
|
| 49 | + | return 0 |
|
| 50 | + | done |
|
| 51 | + | return 1 |
|
| 52 | + | } |
|
| 53 | + | ||
| 54 | + | # wired link carrying traffic. Only consulted once wifi has come up empty, |
|
| 55 | + | # so a working wifi connection always wins the block. |
|
| 56 | + | fallback() { |
|
| 57 | + | [ "$WIFI_ONLY" -eq 1 ] && return 1 |
|
| 58 | + | WIRED=$(wired_iface) || return 1 |
|
| 59 | + | say "" "$WIRED" |
|
| 60 | + | exit 0 |
|
| 61 | + | } |
|
| 62 | + | ||
| 63 | + | if [ -n "${1:-}" ]; then |
|
| 64 | + | # An explicitly named interface is the whole question — no wired fallback, |
|
| 65 | + | # so callers like wifi-connect report on the link they just brought up. |
|
| 66 | + | IFACE="$1" |
|
| 67 | + | WIFI_ONLY=1 |
|
| 68 | + | else |
|
| 69 | + | # Ask the kernel which interfaces are wireless rather than assuming wlan0. |
|
| 70 | + | IFACE=$(iw dev 2>/dev/null | awk '$1 == "Interface" { print $2; exit }') |
|
| 71 | + | fi |
|
| 25 | 72 | ||
| 26 | 73 | # no wireless hardware at all, card present but down/unassociated, |
|
| 27 | 74 | # associated without a lease, connected at rising signal strength. |
|
| 28 | 75 | if [ -z "$IFACE" ]; then |
|
| 76 | + | fallback |
|
| 29 | 77 | say "" "none" |
|
| 30 | 78 | exit 0 |
|
| 31 | 79 | fi |
|
| 32 | 80 | ||
| 33 | 81 | # `iw link` prints "Not connected." while the card is up but unassociated, and |
|
| 34 | 82 | # fails outright once wifi-disable has downed the link. |
|
| 35 | - | LINK=$(iw dev "$IFACE" link 2>/dev/null) || { say "" "off"; exit 0; } |
|
| 83 | + | LINK=$(iw dev "$IFACE" link 2>/dev/null) || { fallback; say "" "off"; exit 0; } |
|
| 36 | 84 | ||
| 37 | 85 | case "$LINK" in |
|
| 38 | 86 | "Connected to"*) ;; |
|
| 39 | - | *) say "" "off"; exit 0 ;; |
|
| 87 | + | *) fallback; say "" "off"; exit 0 ;; |
|
| 40 | 88 | esac |
|
| 41 | 89 | ||
| 42 | 90 | SSID=$(printf '%s\n' "$LINK" | sed -n 's/^[[:space:]]*SSID: \(..*\)$/\1/p') |
|
| 43 | 91 | [ -n "$SSID" ] || SSID="unknown" |
|
| 44 | 92 | ||
| 45 | - | # Associated but without a lease carries no traffic — say so rather than |
|
| 46 | - | # showing a network name that looks connected. |
|
| 93 | + | # Associated but without a lease carries no traffic, so wired wins here too; |
|
| 94 | + | # without one, name the network but say the lease is missing rather than |
|
| 95 | + | # showing an SSID that looks connected. |
|
| 47 | 96 | if ! ip addr show "$IFACE" 2>/dev/null | grep -q "inet "; then |
|
| 97 | + | fallback |
|
| 48 | 98 | say "" "$SSID (no ip)" |
|
| 49 | 99 | exit 0 |
|
| 50 | 100 | fi |
|
| 53 | 103 | # -50 is excellent, -70 is the edge of usable. |
|
| 54 | 104 | DBM=$(printf '%s\n' "$LINK" | awk '/signal:/ { printf "%d", $2; exit }') |
|
| 55 | 105 | ||
| 56 | - | if [ -z "$DBM" ]; then ICON="" # no signal line (some drivers) — assume good |
|
| 106 | + | if [ -z "$DBM" ]; then ICON="" # no signal line (some drivers) — assume good |
|
| 57 | 107 | elif [ "$DBM" -ge -50 ]; then ICON="" |
|
| 58 | 108 | elif [ "$DBM" -ge -60 ]; then ICON="" |
|
| 59 | 109 | elif [ "$DBM" -ge -70 ]; then ICON="" |
|
| 60 | - | else ICON="" |
|
| 110 | + | else ICON="" |
|
| 61 | 111 | fi |
|
| 62 | 112 | ||
| 63 | 113 | say "$ICON" "$SSID" |
|