commits
tags
#!/bin/bash
# status
# Snabb översikt över skrivbordet: WM-stacken, bakgrundsdaemons, systemd-
# tjänster, nätverk, bluetooth, ljud, batteri och skärm/lock-läge. Rör inget,
# bara läser av och skriver ut.
if [ -t 1 ] && command -v tput >/dev/null 2>&1 && [ "$(tput colors 2>/dev/null)" -ge 8 ]; then
C_HEAD=$(tput bold)$(tput setaf 3) # gul
C_OK=$(tput setaf 2) # grön
C_BAD=$(tput setaf 1) # röd
C_DIM=$(tput dim)
C_RESET=$(tput sgr0)
else
C_HEAD=""; C_OK=""; C_BAD=""; C_DIM=""; C_RESET=""
fi
header() { printf "\n%s== %s ==%s\n" "$C_HEAD" "$1" "$C_RESET"; }
ok() { printf " %s✔%s %s\n" "$C_OK" "$C_RESET" "$1"; }
bad() { printf " %s✘%s %s\n" "$C_BAD" "$C_RESET" "$1"; }
line() { printf " %s\n" "$1"; }
proc_status() {
local label="$1" pattern="$2"
local pid
# pgrep -x trunkerar mot /proc/[pid]/comm (max 15 tecken), vilket ger
# falska negativ för längre namn som "lid-display-watch". Matchar
# istället mot hela kommandoraden med en ord-gräns runt namnet.
pid=$(pgrep -f "(^|/)${pattern}([[:space:]]|\$)" | head -1)
if [ -n "$pid" ]; then
ok "$label (pid $pid)"
else
bad "$label - körs inte"
fi
}
strip_ansi() { sed -e 's/\x1b\[[0-9;]*m//g'; }
service_status() {
local scope="$1" name="$2"
local -a scope_args=()
[ -n "$scope" ] && scope_args=("$scope")
if systemctl "${scope_args[@]}" is-active --quiet "$name" 2>/dev/null; then
ok "$name"
else
bad "$name - $(systemctl "${scope_args[@]}" is-active "$name" 2>/dev/null)"
fi
}
header "System"
line "$(hostname) - $(uptime -p 2>/dev/null | sed 's/^up //') - load: $(cut -d' ' -f1-3 /proc/loadavg)"
line "kernel: $(uname -r)"
header "Skrivbord"
proc_status "Xorg" Xorg
proc_status "sxwm" sxwm
proc_status "sxbar" sxbar
proc_status "screensaverd" screensaverd
proc_status "lid-display-watch" lid-display-watch
header "Tjänster"
service_status "" bluetooth
service_status "--user" pipewire
service_status "--user" pipewire-pulse
service_status "--user" wireplumber
header "Nätverk"
while read -r ifc state addr _; do
[ "$ifc" = "lo" ] && continue
if [ "$state" = "UP" ]; then
ok "$ifc: $addr"
else
bad "$ifc: nere"
fi
done < <(ip -br addr show 2>/dev/null)
if command -v iwctl >/dev/null 2>&1; then
while read -r wifi_dev; do
[ -n "$wifi_dev" ] || continue
ssid=$(iwctl station "$wifi_dev" show 2>/dev/null | strip_ansi | sed -n 's/^[[:space:]]*Connected network[[:space:]]\+//p' | sed 's/[[:space:]]*$//')
[ -n "$ssid" ] && line "wifi ($wifi_dev): ansluten till \"$ssid\""
done < <(iwctl station list 2>/dev/null | strip_ansi | awk '/connected/{print $1}')
fi
header "Bluetooth"
if command -v bluetoothctl >/dev/null 2>&1; then
powered=$(bluetoothctl show 2>/dev/null | awk -F': ' '/^\tPowered:/{print $2}')
if [ "$powered" = "yes" ]; then
ok "adapter på"
else
bad "adapter av"
fi
connected=$(bluetoothctl devices Connected 2>/dev/null)
if [ -n "$connected" ]; then
while read -r _ mac name; do
ok "ansluten: $name ($mac)"
done <<< "$connected"
else
line "${C_DIM}inga anslutna enheter${C_RESET}"
fi
else
bad "bluetoothctl saknas"
fi
header "Ljud"
if command -v wpctl >/dev/null 2>&1; then
sink_vol=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ 2>/dev/null)
if [ -n "$sink_vol" ]; then
if echo "$sink_vol" | grep -q MUTED; then
bad "output: $sink_vol"
else
ok "output: $sink_vol"
fi
else
bad "ingen default-output"
fi
else
bad "wpctl saknas"
fi
header "Batteri"
for supply in /sys/class/power_supply/*/; do
name=$(basename "$supply")
type=$(cat "${supply}type" 2>/dev/null)
case "$type" in
Battery)
cap=$(cat "${supply}capacity" 2>/dev/null)
st=$(cat "${supply}status" 2>/dev/null)
if [ "$st" = "Charging" ] || { [ -n "$cap" ] && [ "$cap" -gt 20 ] 2>/dev/null; }; then
ok "$name: $cap% ($st)"
else
bad "$name: $cap% ($st)"
fi
;;
Mains|USB)
online=$(cat "${supply}online" 2>/dev/null)
if [ "$online" = "1" ]; then
line "$name: ansluten"
else
line "$name: inte ansluten"
fi
;;
esac
done
header "Skärm / lock"
dpms=$(xset q 2>/dev/null | awk '/Monitor is/{print $NF}')
[ -n "$dpms" ] && line "DPMS: $dpms"
lid=$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 \
org.freedesktop.login1.Manager LidClosed 2>/dev/null | awk '{print $2}')
case "$lid" in
true) line "lock: stängt" ;;
false) line "lock: öppet" ;;
esac
handle=$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 \
org.freedesktop.login1.Manager HandleLidSwitch 2>/dev/null | cut -d'"' -f2)
[ -n "$handle" ] && line "HandleLidSwitch: $handle"
if command -v lidsuspend >/dev/null 2>&1; then
line "lidsuspend: $(lidsuspend status 2>/dev/null)"
fi
pause_file="${XDG_RUNTIME_DIR:-/tmp}/screensaver-paused"
[ -e "$pause_file" ] && line "screensaver: pausad"
if command -v playerctl >/dev/null 2>&1; then
pstatus=$(playerctl status 2>/dev/null)
if [ "$pstatus" = "Playing" ]; then
header "Media"
ok "$(playerctl metadata --format '{{artist}} - {{title}}' 2>/dev/null)"
fi
fi
echo