nnscripts

no-nonsense shell script colection for Linux-based environments
git clone git://git.luxferre.top/nnscripts.git
Log | Files | Refs | README | LICENSE

nnstatus.sh (3313B)


      1 #!/bin/sh
      2 # nnstatus.sh: no-nonsense status line script (Linux-specific, Xorg-specific)
      3 # only depends on awk (I recommend nawk/one-true-awk) to work with POSIX shells
      4 # and amixer to work with sound and xkb-switch to work with layouts
      5 # and iw + nnwifi.sh to work with wireless networks
      6 # can be redirected to dzen2 or other similar status apps
      7 # (my config is for dzen2)
      8 # created by Luxferre in 2023, released into public domain
      9 
     10 # configure some parameters here
     11 AWK_CMD=nawk # your awk engine
     12 DELIM=' | ' # delimiter between the fields 
     13 SLEEP_INTERVAL=1 # data refresh interval (in seconds)
     14 BATDEV='BAT0' # battery device indicator, if applicable (unset to disable)
     15 MIXER_CHAN='Master' # ALSA channel to control
     16 BARFONT='FiraCode Nerd Font Ret:size=12' # font to use
     17 BAROPTS="-expand left -bg #00040a" # other dzen2 options
     18 
     19 BATDIR="/sys/class/power_supply/$BATDEV"
     20 MYPID="$$"
     21 SENDTRIG="kill -s usr1 $MYPID"
     22 
     23 echo "PID: $MYPID"
     24 
     25 # helper functions
     26 
     27 trap immediate_render INT USR1
     28 
     29 cpustat() { # returns: Idle NonIdle
     30   $AWK_CMD 'NR==1{printf("%u %u", $5+$6, $2+$3+$4+$7+$8+$9)}' /proc/stat
     31 }
     32 
     33 ramstat() { # print used RAM
     34   $AWK_CMD '/^MemTotal:/{mt=$2}/^Buffers:/{mb=$2}/^MemFree:/{mf=$2}\
     35     /^Cached:/{mc=$2}/^Shmem:/{ms=$2}/^SReclaimable:/{msr=$2}\
     36     END{d=mt-mf-mc-msr-mb+ms;if(d<1048576) printf("RAM %4.0fM",d/1024);\
     37     else printf("RAM %4.2fG",d/1048576)}' /proc/meminfo
     38 }
     39 
     40 batstat() { # print battery status
     41   local bstatus="$(cat $BATDIR/status)"
     42   local bpercent="$(cat $BATDIR/capacity)"
     43   local cstatus="CHG" # charging by default
     44   [ "$bstatus" = "Discharging" ] && cstatus="BAT"
     45   printf "%s %03u%%" "$cstatus" "$bpercent"
     46 }
     47 
     48 volstat() {
     49   printf "%s" "^ca(1, amixer sset $MIXER_CHAN toggle && $SENDTRIG)"
     50   printf "%s" "^ca(5, amixer sset $MIXER_CHAN playback 5%+ && $SENDTRIG)"
     51   printf "%s" "^ca(4, amixer sset $MIXER_CHAN playback 5%- && $SENDTRIG)"
     52   amixer sget $MIXER_CHAN | $AWK_CMD 'BEGIN{acc=0;c=0;con=1}\
     53     /\[[0-9][0-9]*\%\]/{for(i=1;i<=NF;i++){\
     54     if($i ~ /\[[0-9][0-9]*\%\]/){acc+=int(substr($i,2));c++}\
     55     if($i ~ /\[off\]/){con=0}\
     56     }}END{printf(con?"VOL %03u%%":"VOL OFF ",int(acc/c))}'
     57   printf "%s" "^ca()^ca()^ca()"
     58 }
     59 
     60 kbdstat() { # keyboard layout
     61   printf "%s" "^ca(1, xkb-switch -n && $SENDTRIG)"
     62   printf "%s^ca()" "$(xkb-switch -p | head -c2)"
     63 }
     64 
     65 wlanstat() {
     66   local ssid="$(iw dev $1 link | $AWK_CMD '/SSID:/{print $2}')"
     67   printf "%s" "^ca(1, xterm -e doas sh nnwifi.sh conf)"
     68   printf "%s: " "$1"
     69   [ -z "$ssid" ] && printf "None" || printf "%s" "$ssid" 
     70   printf "^ca()"
     71 }
     72 
     73 PREVSTAT="$(cpustat)"
     74 
     75 # you can reorder the calls here
     76 
     77 render() {
     78   # wifi
     79   wlanstat wlan0
     80   # ram
     81   printf "%s" "$DELIM"
     82   ramstat
     83   # cpu
     84   printf "%s" "$DELIM"
     85   CURSTAT="$(cpustat)"
     86   printf "%s %s" "$PREVSTAT" "$CURSTAT" | $AWK_CMD 'NR==1{t=$3+$4-$2-$1;i=$3-$1;printf("CPU %03d%%",100*(t-i)/t)}'
     87   PREVSTAT="$CURSTAT"
     88   # battery
     89   [ -n "$BATDEV" ] && [ -d "$BATDIR" ] && printf "%s" "$DELIM" && batstat
     90   # volume
     91   printf "%s" "$DELIM"
     92   volstat
     93   #layout
     94   printf "%s" "$DELIM"
     95   kbdstat
     96   # clock
     97   printf "%s\n" "$DELIM$(date +'%a %b %d %H:%M')"
     98 }
     99 
    100 immediate_render() { # called on SIGINT and SIGUSR1
    101   render | dzen2 -p $SLEEP_INTERVAL -fn "$BARFONT" $BAROPTS
    102 }
    103 
    104 while true; do # main loop
    105   sleep $SLEEP_INTERVAL
    106   render
    107 done | dzen2 -p -fn "$BARFONT" $BAROPTS