nnscripts

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 311828d427ca1f3fe61a5de97ad22a4a6bf84342
Author: Luxferre <lux@ferre>
Date:   Fri, 28 Jul 2023 22:05:58 +0300

initial upload

Diffstat:
ACOPYING | 24++++++++++++++++++++++++
AREADME.md | 16++++++++++++++++
Annlight.sh | 26++++++++++++++++++++++++++
Annstatus.sh | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Annwifi.sh | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 240 insertions(+), 0 deletions(-)

diff --git a/COPYING b/COPYING @@ -0,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> diff --git a/README.md b/README.md @@ -0,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 diff --git a/nnlight.sh b/nnlight.sh @@ -0,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 + diff --git a/nnstatus.sh b/nnstatus.sh @@ -0,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 diff --git a/nnwifi.sh b/nnwifi.sh @@ -0,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