~luxferre/nnscripts

311828d427ca1f3fe61a5de97ad22a4a6bf84342 — Luxferre 1 year, 2 months ago
initial upload
5 files changed, 239 insertions(+), 0 deletions(-)

A COPYING
A README.md
A nnlight.sh
A nnstatus.sh
A nnwifi.sh
A  => COPYING +24 -0
@@ 1,24 @@
This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <https://unlicense.org>

A  => README.md +15 -0
@@ 1,15 @@
# no-nonsense shell scripts

This is a set of (mostly Linux-specific unless stated otherwise) various useful shell scripts that aim to be lightweight and portable across different shells. All scripts were tested on `busybox sh` and `oksh`. The list is going to be updated from time to time. Please see the source code comments for usage guides.

## Current script list

- `nnwifi.sh`: easily set up a WiFi connection (depends on `ip`, `iw`, `wpa_supplicant` and `udhcpc`)
- `nnlight.sh`: control laptop screen brightness (depends on `nawk` or other AWK command)
- `nnstatus.sh`: output useful status information to dzen2 panel (Xorg-specific but can be rewritten to use any other panel of your choice, depends on `nawk` or other AWK command, `iw` for WLAN stats, `amixer` for volume controls and xkb-switch for keyboard layout controls)

## Credits

All scripts in this repo were created by Luxferre starting from 2023 and released into public domain.

Made in Ukraine.
\ No newline at end of file

A  => nnlight.sh +26 -0
@@ 1,26 @@
#!/bin/sh
# no-nonsense backlight manager (Linux-specific)
# usage: sh nnlight.sh [value|+value|-value|?]
# the script must be run as root
# (can configure in /etc/doas.conf to run without password)
# Created by Luxferre in 2023, released into public domain

RAWVAL="$1"
AWK_CMD=nawk # override if you need

# attempt to autodetect the backlight driver
# you can override the BRFILE variable manually if it fails

RBLD="/sys/class/backlight"
BNAME="$(ls -l $RBLD | $AWK_CMD -F / '/LVDS|eDP/{print $NF}')"
BRFILE="$RBLD/$BNAME/brightness"

CURVAL="$(cat $BRFILE)" # get current brightness
SUBVAL="${RAWVAL#?}" # remove the first char from input
case "$RAWVAL" in
 \?) printf "%u\n" "$CURVAL" ;;
 +*) printf "%u" "$((CURVAL + SUBVAL))" > $BRFILE ;;
 -*) printf "%u" "$((CURVAL - SUBVAL))" > $BRFILE ;;
 *) printf "%u" "$RAWVAL" > $BRFILE ;;
esac


A  => nnstatus.sh +107 -0
@@ 1,107 @@
#!/bin/sh
# nnstatus.sh: no-nonsense status line script (Linux-specific, Xorg-specific)
# only depends on awk (I recommend nawk/one-true-awk) to work with POSIX shells
# and amixer to work with sound and xkb-switch to work with layouts
# and iw + nnwifi.sh to work with wireless networks
# can be redirected to dzen2 or other similar status apps
# (my config is for dzen2)
# created by Luxferre in 2023, released into public domain

# configure some parameters here
AWK_CMD=nawk # your awk engine
DELIM=' | ' # delimiter between the fields 
SLEEP_INTERVAL=1 # data refresh interval (in seconds)
BATDEV='BAT0' # battery device indicator, if applicable (unset to disable)
MIXER_CHAN='Master' # ALSA channel to control
BARFONT='FiraCode Nerd Font Ret:size=12' # font to use
BAROPTS="-expand left -bg #00040a" # other dzen2 options

BATDIR="/sys/class/power_supply/$BATDEV"
MYPID="$$"
SENDTRIG="kill -s usr1 $MYPID"

echo "PID: $MYPID"

# helper functions

trap immediate_render INT USR1

cpustat() { # returns: Idle NonIdle
  $AWK_CMD 'NR==1{printf("%u %u", $5+$6, $2+$3+$4+$7+$8+$9)}' /proc/stat
}

ramstat() { # print used RAM
  $AWK_CMD '/^MemTotal:/{mt=$2}/^Buffers:/{mb=$2}/^MemFree:/{mf=$2}\
    /^Cached:/{mc=$2}/^Shmem:/{ms=$2}/^SReclaimable:/{msr=$2}\
    END{d=mt-mf-mc-msr-mb+ms;if(d<1048576) printf("RAM %4.0fM",d/1024);\
    else printf("RAM %4.2fG",d/1048576)}' /proc/meminfo
}

batstat() { # print battery status
  local bstatus="$(cat $BATDIR/status)"
  local bpercent="$(cat $BATDIR/capacity)"
  local cstatus="CHG" # charging by default
  [ "$bstatus" = "Discharging" ] && cstatus="BAT"
  printf "%s %03u%%" "$cstatus" "$bpercent"
}

volstat() {
  printf "%s" "^ca(1, amixer sset $MIXER_CHAN toggle && $SENDTRIG)"
  printf "%s" "^ca(5, amixer sset $MIXER_CHAN playback 5%+ && $SENDTRIG)"
  printf "%s" "^ca(4, amixer sset $MIXER_CHAN playback 5%- && $SENDTRIG)"
  amixer sget $MIXER_CHAN | $AWK_CMD 'BEGIN{acc=0;c=0;con=1}\
    /\[[0-9][0-9]*\%\]/{for(i=1;i<=NF;i++){\
    if($i ~ /\[[0-9][0-9]*\%\]/){acc+=int(substr($i,2));c++}\
    if($i ~ /\[off\]/){con=0}\
    }}END{printf(con?"VOL %03u%%":"VOL OFF ",int(acc/c))}'
  printf "%s" "^ca()^ca()^ca()"
}

kbdstat() { # keyboard layout
  printf "%s" "^ca(1, xkb-switch -n && $SENDTRIG)"
  printf "%s^ca()" "$(xkb-switch -p | head -c2)"
}

wlanstat() {
  local ssid="$(iw dev $1 link | $AWK_CMD '/SSID:/{print $2}')"
  printf "%s" "^ca(1, xterm -e doas sh nnwifi.sh conf)"
  printf "%s: " "$1"
  [ -z "$ssid" ] && printf "None" || printf "%s" "$ssid" 
  printf "^ca()"
}

PREVSTAT="$(cpustat)"

# you can reorder the calls here

render() {
  # wifi
  wlanstat wlan0
  # ram
  printf "%s" "$DELIM"
  ramstat
  # cpu
  printf "%s" "$DELIM"
  CURSTAT="$(cpustat)"
  printf "%s %s" "$PREVSTAT" "$CURSTAT" | $AWK_CMD 'NR==1{t=$3+$4-$2-$1;i=$3-$1;printf("CPU %03d%%",100*(t-i)/t)}'
  PREVSTAT="$CURSTAT"
  # battery
  [ -n "$BATDEV" ] && [ -d "$BATDIR" ] && printf "%s" "$DELIM" && batstat
  # volume
  printf "%s" "$DELIM"
  volstat
  #layout
  printf "%s" "$DELIM"
  kbdstat
  # clock
  printf "%s\n" "$DELIM$(date +'%a %b %d %H:%M')"
}

immediate_render() { # called on SIGINT and SIGUSR1
  render | dzen2 -p $SLEEP_INTERVAL -fn "$BARFONT" $BAROPTS
}

while true; do # main loop
  sleep $SLEEP_INTERVAL
  render
done | dzen2 -p -fn "$BARFONT" $BAROPTS

A  => nnwifi.sh +67 -0
@@ 1,67 @@
#!/bin/sh
# Universal wifi setup for lightweight Linux systems
# depends on wpa_supplicant and udhcpc
# the script must be run as root
# (can configure in /etc/doas.conf to run without password)
# Created by Luxferre in 2023, released into public domain

# config file place
CFG="$HOME/nnwifi.conf"
SSID_HIDDEN=1

[ -f "$CFG" ] && . $CFG # source it

# if "conf", run the interactive prompt
# otherwise use the preconfigured values
if [ "$1" == "conf" ]; then
  printf "Interface[%s]: " "$IFACE"
  read -r INP_IFACE
  printf "Access point[%s]: " "$SSID"
  read -r INP_SSID
  printf "Password[unchanged]: "
  read -r INP_PSK
  printf "Primary DNS[%s]: " "$DNS_PRIMARY"
  read -r INP_DNS_PRIMARY
  printf "Secondary DNS[%s]: " "$DNS_SECONDARY"
  read -r INP_DNS_SECONDARY
  [ -n "$INP_IFACE" ] && IFACE="$INP_IFACE"
  [ -n "$INP_SSID" ] && SSID="$INP_SSID"
  [ -n "$INP_PSK" ] && PSK="$INP_PSK"
  [ -n "$INP_DNS_PRIMARY" ] && DNS_PRIMARY="$INP_DNS_PRIMARY"
  [ -n "$INP_DNS_SECONDARY" ] && DNS_SECONDARY="$INP_DNS_SECONDARY"
  # update the config
cat << ENDCFG > $CFG
IFACE=$IFACE
SSID="$SSID"
PSK="$PSK"
DNS_PRIMARY="$DNS_PRIMARY"
DNS_SECONDARY="$DNS_SECONDARY"
ENDCFG
fi

# most probably you don't need to change these two

SUPFILE="/etc/wpa_supplicant.conf"
SUPCTL="/var/run/wpa_supplicant"

# first template $SUPFILE

cat << ENDSUP > $SUPFILE
ctrl_interface=$SUPCTL
update_config=1
network={
  ssid="$SSID"
  scan_ssid=$SSID_HIDDEN
  psk="$PSK"
}
ENDSUP

# then setup the interface
killall udhcpc
killall wpa_supplicant

ip link set $IFACE up
wpa_supplicant -B -i $IFACE -c $SUPFILE
udhcpc -i $IFACE
echo "nameserver $DNS_PRIMARY" > /etc/resolv.conf
echo "nameserver $DNS_SECONDARY" >> /etc/resolv.conf