Browse Source

Update scripts

Bryan Roessler 2 weeks ago
parent
commit
af725302ba

+ 0 - 2
.gitignore

@@ -1,5 +1,3 @@
 .vscode/
 setup/
-hartmanlab/
-.env
 .old/

+ 0 - 69
shell/btrbk-archive-rsync

@@ -1,69 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2023 Bryan C. Roessler
-#
-# This script replaces btrfs send|receive with rsync for resumable btrbk backups
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-TESTING=1
-
-main() {
-
-  # The source subvolume to backup
-  SRC_SUBVOLUME="$1"
-  # The location of the intermediate btrfs image file
-  # This must be at least the size of SRC (including snapshots) and ideally on fast storage
-  SRC_TMPDIR="$2"
-  # The remote destination
-  DEST_HOST="$3"
-  DEST_TMPDIR="$4"
-  DEST_DIR="$5"
-
-  # Get rid of garbled backups
-  sudo btrbk clean
-
-  # Create raw archive file
-  # TODO Encryption/compression
-  sudo btrbk archive "$SRC_SUBVOLUME" "$SRC_TMPDIR" --raw
-
-  # Retern the latest image
-  # "<snapshot-name>.<timestamp>[_N].btrfs[.gz|.bz2|.xz][.gpg]"
-  #SRC_TMPFILENAME=$(find "$SRC_TMPDIR" -type f -regex '.*/*.btrfs' -printf "%f\n" | tail -1)
-  SRC_FILEPATH="$SRC_TMPDIR/$SRC_FILENAME"
-  DEST_TMPDIR="$DEST_TMPDIR/${SRC_FILENAME%%'.btrfs'}"
-  DEST="$DEST_DIR/${SRC_FILENAME%%'.btrfs'}"
-
-  # shellcheck disable=SC2029
-  sudo rsync \
-    --append-verify \
-    --remove-source-files \
-    "$SRC_FILEPATH" "$DEST:$DEST_TMP" &&
-    ssh "$DEST_HOST" "
-      btrfs receive --verbose --progress -f $DEST_TMP $DEST &&
-      rm -f $DEST_TMPFILE
-    "
-}
-
-# For testing
-if (( TESTING )); then
-  main "${1:"/home/bryan"}" \
-    "${2:"/mnt/temp"}" \
-    "${3:"router"}" \
-    "${4:"/mnt/backup"}" \
-    "${5:"/mnt/backup/workstation/home"}" # TODO Need a separate SSD :-/ # i.e. root@router.lan from ~/.ssh/config
-else
-  # For deploy
-  main "$@"
-fi
-
-exit

+ 0 - 26
shell/btrbkwrap

@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2023 Bryan C. Roessler
-#
-# btrbk wrapper to return latest target subvolume
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-(( EUID > 0 )) && echo "Please run as root." && exit 1
-
-target="$1" # router.lan:/mnt/backup/media/music
-
-shift
-
-btrbk --dry-run "$@" &&
-btrbk list latest --format=col:h:TARGET_HOST,TARGET_SUBVOLUME "$target"

+ 0 - 30
shell/build-remote

@@ -1,30 +0,0 @@
-#!/usr/bin/env bash
-#
-#
-#
-
-#REMOTE_HOST="vm-fedora33"
-
-# Manual
-
-#BUILD_DIR="$PWD"
-#REMOTE_COMMAND="cd $PWD && ./script.sh"
-
-# VSCode
-#REMOTE_HOST="vm-fedora33"
-#BUILD_DIR=${fileWorkspaceFolder}
-#REMOTE_CMD="cd ${fileWorkspaceFolder} && chmod +x ${file} && ${file}"
-
-
-# Copy local directory "$2" to remote host "$1" and run the remaining commands 
-ssh "$1" mkdir -p "$2"
-# Maybe use --delete for a cleaner dev env
-rsync -a "$2/" "$1":"$2"
-# We want this to expand on the client so we can pass our arguments to the remote
-# shellcheck disable=SC2029
-ssh "$1" "${@:2}"
-
-
-
-# exec_remote "$REMOTE_HOST" "$BUILD_DIR" "$REMOTE_CMD"
-#exec_remote vm-fedora33 ${fileWorkspaceFolder} cd ${fileWorkspaceFolder} && chmod +x ${file} && ${file}

+ 0 - 3
shell/create-home

@@ -1,3 +0,0 @@
-#!/usr/bin/env bash
-
-sudo homectl --storage=subvolume --real-name=Bryan --member-of=wheel --shell=/usr/bin/zsh --timezone=America/New_York -P --auto-login=on create bryan

+ 2 - 1
shell/dotfiles-store

@@ -1,8 +1,9 @@
 #!/usr/bin/env bash
 
 dotfiles-store() {
+  [[ $# -lt 2 ]] && { echo "Usage: $0 <subdir> <file1> [<file2> ...]"; return 1; }
   local subdir=$1; shift
-  local dotdir=~/scripts/dotfiles
+  local dotdir=~/develop/dotfiles
   mkdir -p "$dotdir/$subdir"
   for src in "$@"; do
     local filename

+ 0 - 9
shell/download-torrent

@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-#
-# I develop on a laptop and prefer to send torrent files (linux isos, etc.) to my desktop
-#
-# I set .torrent links to open this script by default in firefox
-#
-
-mv "$1" "$HOME/documents/torrents/"
-chmod +rw "$HOME/documents/torrents/"*

+ 0 - 261
shell/fedora-enable-hibernate

@@ -1,261 +0,0 @@
-#!/usr/bin/env bash
-# This program will create a hibernation-ready swapfile in a btrfs subvolume and enable hibernation
-# Copyright Bryan C. Roessler 2021
-# This software is released under the Apache License.
-# https://www.apache.org/licenses/LICENSE-2.0
-# Tested on: Fedora 34
-
-VERBOSE=true
-function init() {
-
-    SWAP_FILE=${SWAP_FILE:-"/.swap/swapfile"}
-
-    [[ "$#" -lt 1 ]] && return 0
-
-    if input=$(getopt -s v -l image-size:,swap-size:,swap-file:,device-uuid:,verbose -- "$@"); then
-        eval set -- "$input"
-        while true; do
-            case "$1" in
-                --image-size)
-                    shift && IMAGE_SIZE="$1"
-                    ;;
-                --swap-size)
-                    shift && SWAP_SIZE="$1"
-                    ;;
-                --swap-file)
-                    declare -x SWAP_FILE
-                    shift && SWAP_FILE="$1"
-                    ;;
-                --device-uuid)
-                    shift && DEVICE_UUID="$1"
-                    ;;
-                --verbose|v)
-                    VERBOSE=true
-                    ;;
-                --)
-                    shift
-                    break
-                    ;;
-            esac
-            shift
-        done
-    else
-        echo "Incorrect option provided"
-        exit 1
-    fi
-}
-
-
-function debug() {
-    [[ "$VERBOSE" == true ]] && echo "$@"
-}
-
-
-function get_mem_size() {
-    declare -ig MEM_SIZE MEM_SIZE_GB
-    MEM_SIZE=$(free -b | grep "Mem:" | tr -s ' ' | cut -d" " -f2)
-    MEM_SIZE_GB=$(numfmt --from=iec --to-unit=G "$MEM_SIZE")
-    debug "MEM_SIZE_GB: ${MEM_SIZE_GB}"
-}
-
-
-#######################################
-# Get user y/N/iec response
-# Arguments:
-#   1. Text to display
-#   2. Global variable name to store response
-#######################################
-function response_iec() {
-    declare _response _response_l _response_u
-    read -r -p "$* [y/N/iec]: " _response
-    _response_l="${_response,,}"
-    _response_u="${_response^^}"
-    [[ "$_response_l" =~ ^(yes|y) ]] && return 0
-    if [[ "$_response" =~ ^([[:digit:]]+[[:alnum:]])$ || "$_response" =~ ^([[:digit:]]+)$ ]]; then
-        if ! declare -gi "$2"="$(numfmt --from=iec "$_response_u")"; then
-            echo "$_response is not a valid IEC value (ex. 42 512K 10M 7G 3.5T)"
-            return 1
-        else
-            declare -gi "$2"_GB="$(numfmt --from=iec --to-unit=Gi "$_response_u")"
-            return 0
-        fi
-    fi
-    exit 1
-}
-
-
-function set_swap_size() {
-    declare -gi SWAP_SIZE_GB
-    declare _response _response_l
-
-    # By default make the swapfile size the same as the system RAM
-    # This is the safest approach at the expense of disk space
-    # You can improve hibernation speed by tweaking $IMAGE_SIZE instead.
-    [[ ! -v SWAP_SIZE ]] && SWAP_SIZE=$MEM_SIZE
-
-    #SWAP_SIZE_MB=$(numfmt --from=iec --to-unit=Mi "$SWAP_SIZE")
-    SWAP_SIZE_GB=$(numfmt --from=iec  --to-unit=G "$SWAP_SIZE")
-    
-    # TODO incrementally use increasing IEC nominators 
-    echo "Ideal swapfile size is equal to system RAM: ${MEM_SIZE_GB}G"
-    
-    # TODO See above, also for image size
-    until response_iec "Set swapfile size to ${SWAP_SIZE_GB}G?" "SWAP_SIZE"; do
-        echo "Retrying..."
-    done
-    debug "SWAP_SIZE_GB: ${SWAP_SIZE_GB}G"
-}
-
-
-function set_image_size() {
-    declare _response _response_l
-    declare -i mem_size_target current_image_size current_image_size_gb
-
-    # Set ideal image size
-    if [[ ! -v IMAGE_SIZE ]]; then
-        # Sensible default (greater of 1/4 swapfile or ram size)
-        mem_size_target=$(( MEM_SIZE / 4 ))
-        swap_size_target=$(( SWAP_SIZE / 4 ))
-        IMAGE_SIZE=$(( mem_size_target > swap_size_target ? mem_size_target : swap_size_target ))
-        IMAGE_SIZE_GB=$(numfmt --from=iec --to-unit=G "$IMAGE_SIZE")
-    fi
-
-    current_image_size=$(cat /sys/power/image_size)
-    current_image_size_gb=$(numfmt --from=iec --to-unit=G "$current_image_size")
-  
-    echo "Ideal image target size is 1/4 of the RAM or swapfile size"
-    echo "Swapfile size: ${SWAP_SIZE_GB}G"
-    echo "RAM size: ${MEM_SIZE_GB}G"
-    until response_iec "Resize /sys/power/image_size from ${current_image_size_gb}G to ${IMAGE_SIZE_GB}G?" "IMAGE_SIZE"; do
-        echo "Retrying..."
-    done
-
-    debug "IMAGE_SIZE_GB: ${IMAGE_SIZE_GB}G"
-}
-
-
-function write_image_size() {
-    echo "$IMAGE_SIZE_GB" | sudo tee /sys/power/image_size
-}
-
-
-function make_swapfile () {
-    declare parent_dir
-    parent_dir=$(dirname "$SWAP_FILE")
-    ! [[ -d "$parent_dir" ]] && \
-        if ! sudo btrfs sub create "$parent_dir"; then
-            echo "Could not create a btrfs subvolume at $parent_dir"
-            echo "Please check your permissions/filesystem"
-            exit 1
-        fi
-    sudo touch "$SWAP_FILE"
-    #sudo truncate -s 0 "$SWAP_FILE"
-    sudo chattr +C "$SWAP_FILE"
-    sudo fallocate --length "$SWAP_SIZE" "$SWAP_FILE"
-    #sudo btrfs property set "$SWAP_FILE" compression none
-    #sudo dd if=/dev/zero of="$SWAP_FILE" bs=1M count="$SWAP_SIZE_MB" status=progress
-    sudo chmod 600 "$SWAP_FILE"
-    sudo mkswap "$SWAP_FILE"
-    #sudo swapon "$SWAP_FILE"
-}
-
-
-function add_to_dracut() {
-    echo 'add_dracutmodules+=" resume "' | sudo tee /etc/dracut.conf.d/50-resume.conf
-    sudo dracut -f
-}
-
-
-# function add_to_fstab() {
-#     echo "Backing up /etc/fstab to /tmp/fstab.bk"
-#     cp /etc/fstab /tmp/fstab.bk
-#     echo "$SWAP_FILE	none	swap	sw 0 0" | sudo tee -a /etc/fstab
-# }
-
-
-function get_offset() {
-    physical_offset=$(./btrfs_map_physical "$SWAP_FILE" | head -n2 | tail -n1 | cut -f9)
-    debug "Physical offset: $physical_offset"
-}
-
-
-function get_device() {
-    if ! [[ -v DEVICE_UUID ]]; then
-        DEVICE_UUID=$(findmnt -no UUID -T "$SWAP_FILE")
-        # if ! DEVICE_UUID=$(sudo blkid | grep /dev/mapper/luks | cut -d' ' -f3); then
-        #     echo "Guessing device UUID failed. Please specify a --device-uuid and rerun"
-        #     exit 1
-        # fi
-    fi
-    if [[ ! $DEVICE_UUID == ^UUID=* ]]; then
-        DEVICE_UUID="UUID=${DEVICE_UUID}"
-    fi
-    debug "Device UUID: $DEVICE_UUID"
-}
-
-
-function get_offset() {
-    declare -i physical_offset 
-
-    [[ -v RESUME_OFFSET ]] && return 0
-
-    RESUME_OFFSET=$(sudo filefrag -v "$SWAP_FILE" | head -n 4 | tail -n 1 | awk '{print $4}')
-    
-    # tempdir="$(mktemp --directory --tmpdir= enable-hibernate-XXXXXXXXX)"
-    # pushd "$tempdir" || return 1
-    # curl -O "https://raw.githubusercontent.com/osandov/osandov-linux/master/scripts/btrfs_map_physical.c"
-    # gcc -O2 -o btrfs_map_physical btrfs_map_physical.c
-    # page_size=$(getconf PAGESIZE)
-    # # ./btrfs_map_physical "$SWAP_FILE" | head -n2 | tail -n1 | cut -f9
-    # sudo bash -c "export physical_offset=$(./btrfs_map_physical "$SWAP_FILE" | head -n2 | tail -n1 | cut -f9);"
-    # echo "$physical_offset"
-    # popd || return 1
-    # rm -rf "$tempdir"
-    # RESUME_OFFSET=$(( physical_offset / page_size ))
-    debug "Resume offset: $RESUME_OFFSET"
-}
-
-
-function update_grub() {
-    echo "Backing up /etc/default/grub to /tmp/grub.bk"
-    cp /etc/default/grub /tmp/grub.bk
-    if grub_cmdline_linux=$(grep GRUB_CMDLINE_LINUX /etc/default/grub); then
-        if [[ $grub_cmdline_linux == *resume=* ]]; then
-            sudo sed -i "s/resume=.* /resume=${DEVICE_UUID} /" /etc/default/grub
-            sudo sed -i "s/resume_offset=.* /resume_offset=${RESUME_OFFSET} /" /etc/default/grub
-        else
-            sudo sed -i "s/GRUB_CMDLINE_LINUX_DEFAULT.*/& resume=${DEVICE_UUID} resume_offset=${RESUME_OFFSET}/" /etc/default/grub
-        fi
-    else
-        echo "Your /etc/default/grub cannot be edited automatically, please add: "
-        echo "resume=${DEVICE_UUID} resume_offset=${RESUME_OFFSET}"
-        echo "...to your kernel command line in /etc/default/grub,"
-        echo 'and run "sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg"'
-        exit 1
-    fi
-    
-    sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
-}
-
-
-function live_apply() {
-    #declare devid
-    #devid=$(lsblk | grep luks |cut -d' ' -f4)
-    echo "${RESUME_OFFSET}" | sudo tee /sys/power/resume_offset
-}
-
-
-function main() {
-    init "$@" && \
-    get_mem_size && \
-    set_swap_size && \
-    set_image_size && \
-    make_swapfile && \
-    get_offset && \
-    add_to_dracut && \
-    update_grub && \
-    suggest_reboot
-}
-
-main "$@"
-exit $?

+ 2 - 6
shell/history-clean

@@ -1,11 +1,7 @@
 #!/usr/bin/env bash
-# This script will clean the history file of sensitive info
-#
+# This script will clean the history file of PGP messages and keys
 
 histfile="${1:-$HISTFILE:-$HOME/.histfile}"
-
 cp -a "$histfile" "/tmp/$histfile.bak"
-
 sed --in-place '/gpg/d' "$histfile"
-
-sed --in-place '/-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/d' "$histfile"
+sed --in-place '/-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/d' "$histfile"

+ 0 - 74
shell/installpkg

@@ -1,74 +0,0 @@
-#!/usr/bin/env bash
-# Identify host OS and execute package manager install command on input args
-#
-
-installpkg() {
-
-	getOS() {
-
-		# Widely supported method to retrieve host $ID
-		if [[ -e /etc/os-release ]]; then
-		    source /etc/os-release
-		else
-		    echo "No /etc/os-release found!"
-		    echo "Your OS is unsupported!"
-		    return 1
-		fi
-	}
-
-
-	setCmdArr () {
-
-		declare -ga CMD_ARR
-
-		# Create OS-specific package install command arrays
-		if [[ "$ID" == "fedora" ]]; then
-			CMD_ARR=( "dnf" "install" "-y" )
-		elif [[ "$ID" == "centos" && "$VERSION_ID" -ge 8 ]]; then
-			CMD_ARR=( "dnf" "install" "-y" )
-		elif [[ "$ID" == "centos" && "$VERSION_ID" -le 7 ]]; then
-			CMD_ARR=( "yum" "install" "-y" )
-		elif [[ "$ID" == "ubuntu" || "$ID" == "debian" ]]; then
-			CMD_ARR=( "apt-get" "install" "-y" )
-		elif [[ "$ID" == "arch" ]]; then
-			CMD_ARR=( "pacman" "-Syu" )
-		else
-			echo "Your OS is currently unsupported! You are welcome to add your own and submit a PR."
-			return 1
-		fi
-
-		# Append sudo if not running as root
-		[[ "$(whoami)" != "root" ]] && CMD_ARR=( "sudo" "${CMD_ARR[@]}" )
-	}
-
-
-	installPackage() {
-
-		# Check for input arguments
-		if [[ "$#" -ge 1 ]]; then
-			if ! "${CMD_ARR[@]}" "$@"; then
-				echo "Installation failed!"
-				return 1
-			fi
-		else
-			echo "You must supply one or more packages to install!"
-			return 1
-		fi
-	}
-
-
-	main() {
-
-		getOS && \
-		setCmdArr && \
-		installPackage "$@" && \
-        unset CMD_ARR
-	}
-
-	main "$@"
-}
-
-if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
-	installpkg "$@"
-	exit $?
-fi

+ 62 - 71
shell/prunefiles

@@ -1,79 +1,70 @@
 #!/usr/bin/env bash
-# prunefiles, a script/function to remove all but the n latest versions of a file
-#
+# Remove all but the latest N versions of files matching given prefixes
+# See prunefiles --help for usage
 
-prunefiles () {
-
-    declare -ag PREFIXES
-    declare -g KEEP_INT=1 # default # of files to keep
-
-    printHelpAndExit () {
+prunefiles() {
+  declare -ag PREFIXES
+  declare -g KEEP_INT=1 # default number of files to keep
 
+  printHelpAndExit() {
     cat <<-'EOF'
-		USAGE:
-		    pruneFiles -k 3 thisfileprefix [thatfileprefix]
-
-		OPTIONS
-		    -k, --keep NUMBER
-		        Keep NUMBER of latest files that matches each file prefix (Default: 1)
-		    -h, --help
-		        Print this help dialog and exit
-	EOF
-
-    # Exit using passed exit code
-    [[ -z $1 ]] && exit 0 || exit "$1"
-
-    }
-
-    parseInput () {
-
-        if _input=$(getopt -o +hk: -l help,keep: -- "$@"); then
-            eval set -- "$_input"
-            while true; do
-                case "$1" in
-                    -k|--keep)
-                        shift && KEEP_INT=$1
-                        ;;
-                    -h|--help)
-                        printHelpAndExit 0
-                        ;;
-                    --)
-                        shift; break
-                        ;;
-                esac
-                shift
-            done
-        else
-            echo "Incorrect option(s) provided"
-            printHelpAndExit 1
-        fi
-
-        PREFIXES=( "$@" )
-    }
-
-
-    findAndRemove () {
-
-        declare prefix file
-
-        for prefix in "${PREFIXES[@]}"; do
-            for file in $(find . -maxdepth 1 -type f -name "${prefix}*" -printf '%T@ %p\n' | sort -r -z -n | tail -n+$((KEEP_INT + 1)) | awk '{ print $2; }'); do
-                rm "$file"
-            done
-        done
-    }
-
-
-    main () {
-        parseInput "$@"
-        findAndRemove
-    }
-
-    main "$@"
+			USAGE:
+			  prunefiles -k 3 thisfileprefix [thatfileprefix]
+
+			OPTIONS:
+			  -k, --keep NUMBER
+			    Keep NUMBER of the latest files that match each file prefix (Default: 1)
+			  -h, --help
+			    Print this help dialog and exit
+		EOF
+    [[ -z "$1" ]] && exit 0 || exit "$1"
+  }
+
+  parseInput() {
+    if _input=$(getopt -o hk: -l help,keep: -- "$@"); then
+      eval set -- "$_input"
+      while true; do
+        case "$1" in
+          -k|--keep) shift; KEEP_INT="$1" ;;
+          -h|--help) printHelpAndExit 0 ;;
+          --) shift; break ;;
+        esac
+        shift
+      done
+    else
+      echo "Incorrect option(s) provided"
+      printHelpAndExit 1
+    fi
+    PREFIXES=("$@")
+  }
+
+  findAndRemove() {
+    local prefix file
+
+    for prefix in "${PREFIXES[@]}"; do
+      # List files matching the prefix sorted by modification time (latest first),
+      # then remove all except the first KEEP_INT files.
+      while IFS= read -r file; do
+        echo "Removing: $file"
+        rm -- "$file"
+      done < <(
+        find . -maxdepth 1 -type f -name "${prefix}*" -printf '%T@ %p\n' | \
+        sort -rn | \
+        awk -v keep="$KEEP_INT" 'NR > keep {print $2}'
+      )
+    done
+  }
+
+  main() {
+    parseInput "$@"
+    findAndRemove
+  }
+
+  main "$@"
 }
 
 # Allow script to be safely sourced
 if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
-    prunefiles "$@"
-    exit $?
-fi
+  prunefiles "$@"
+  exit $?
+fi

+ 38 - 9
shell/remove-small-dirs

@@ -1,13 +1,42 @@
 #!/usr/bin/env bash
-[[ $# -eq 0 ]] && echo "You must provide a directory" && exit 1
+# Remove directories below a specified size (in KB)
+# Usage: remove-small-dirs DIRECTORY [SIZE_THRESHOLD]
+# Default SIZE_THRESHOLD is 1000 KB
+
+set -euo pipefail
+
+if [[ $# -lt 1 ]]; then
+    echo "You must provide a directory." >&2
+    exit 1
+fi
+
 dir="$1"
-[[ $# -eq 2 ]] && SIZE="$2" || SIZE=1000 # set the default min dir size
+SIZE="${2:-1000}"
+
+if [[ ! -d "$dir" ]]; then
+    echo "Directory does not exist: $dir" >&2
+    exit 1
+fi
+
+# Find directories with size less or equal to SIZE
+small_dirs=$(find "$dir" -mindepth 1 -type d -exec du -ks {} + | awk -v size="$SIZE" '$1 <= size {print $2}')
+
+if [[ -z "$small_dirs" ]]; then
+    echo "No directories with size <= $SIZE KB found in $dir."
+    exit 0
+fi
+
+echo "Directories to be removed:"
+echo "$small_dirs"
+
+read -r -p "Is this OK? [y/N] " response
+response="${response,,}"  # Convert to lowercase
 
-[[ ! -d "$dir" ]] && echo "Directory does not exist" && exit 1
+if [[ ! "$response" =~ ^(yes|y)$ ]]; then
+    echo "Exiting, no changes were made."
+    exit 0
+fi
 
-# Print dirs to be removed
-find "$dir" -mindepth 1 -type d -exec du -ks {} + | awk -v size="$SIZE" '$1 <= size' | cut -f 2-
-read -r -p "Is this OK? [y/N]" _response
-_response_l="${_response,,}"
-[[ ! "$_response_l" =~ ^(yes|y) ]] && echo "Exiting, no changes were made" && exit 0
-find "$dir" -mindepth 1 -type d -exec du -ks {} + | awk -v size="$SIZE" '$1 <= size' | cut -f 2- | xargs -d'\n' rm -rf
+echo "$small_dirs" | xargs -d'\n' rm -rf
+echo "Removed the following directories:"
+echo "$small_dirs"

+ 0 - 29
shell/rename-gaussian

@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-find . -name "*.gau" -print | xargs sed -i 's/'nproc'/'NProcShared'/g'
-find . -name "*.gau" -print | xargs sed -i 's/'mem=1GB'/'mem=500MB'/g'
-
-find . -name "*.gau" -print | xargs sed -i 's/'nproc=1'/'NProcShared=8'/g'
-find . -name "*.gau" -print | xargs sed -i 's/'mem=1GB'/'mem=8GB'/g'
-
-MYFILES=*.gau
-for f in $MYFILES
-do
-    rung09 $f
-done
-
-for i in {716269..716309}
-do
-    canceljob $i
-done
-
-find . -name "*.gau" -print | xargs sed -i 's/'NProcShared'/'nproc'/g'
-find . -name "*.gau" -print | xargs sed -i 's/'mem=500MB'/'mem=1GB'/g'
-
-find . -name "*.gau" -print | xargs sed -i 's/'NProcShared=8'/'NProcShared=1'/g'
-find . -name "*.gau" -print | xargs sed -i 's/'mem=8GB'/'mem=500MB'/g'
-
-
-daytime
-find . -name "*.gau" -print | xargs sed -i 's/'NProcShared=1'/'NProcShared=2'/g'
-find . -name "*.gau" -print | xargs sed -i 's/'mem=500MB'/'mem=2GB'/g'

+ 0 - 40
shell/rsync-external-backup

@@ -1,40 +0,0 @@
-#!/usr/bin/env bash
-# TODO LEGACY: USE BTRBK
-
-ask_ok() {
-    read -r -p "$* [y/N]: " response
-    response=${response,,}
-    [[ ! "$response" =~ ^(yes|y)$ ]] && return 1
-    return 0
-}
-
-declare -a include_dirs=(
-    "$HOME/music"
-    "$HOME/documents"
-    "$HOME/downloads"
-    "$HOME/pictures"
-    "$HOME/ebooks"
-    "$HOME/devices"
-    "$HOME"/.*
-)
-declare -a exclude_dirs=(
-    "$HOME/.**"
-    "$HOME/..**"
-)
-declare destination="/run/media/bryan/4tb-external/$HOSTNAME"
-declare rsync_cmd="rsync -aAXL --info=progress2 --delete"
-
-for i in "${include_dirs[@]}"; do
-    rsync_cmd+=" --include $i**"
-done
-
-for i in "${exclude_dirs[@]}"; do
-    rsync_cmd+=" --exclude $i"
-done
-
-echo "Command to run: $rsync_cmd $destination"
-ask_ok "Continue?" || exit 1
-
-[[ ! -d "$destination" ]] && mkdir -p "$destination"
-
-eval "$rsync_cmd $destination"

+ 0 - 9
shell/send-torrent-to-htpc

@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-#
-# I develop on a laptop and prefer to send torrent files (linux isos, etc.) to my desktop
-#
-# I set .torrent links to open this script by default in firefox
-#
-
-mv "$1" "$HOME/Documents/torrents/"
-chmod +rw "$HOME/Documents/torrents/$1"

+ 3 - 1
shell/share-link

@@ -1,6 +1,8 @@
 #!/usr/bin/env bash
 # Nautilus script for creating one or more shared links
-# Requires wl-clipboard and notify-send 
+# Requires wl-clipboard and notify-send
+# Copyright 2021-2025 Bryan C. Roessler
+# Licensed under the Apache License, Version 2.0
 
 ssh_server="bryanroessler.com"
 ssh_files_path="/var/www/repos.bryanroessler.com/files"

+ 26 - 23
shell/speedtest-compare

@@ -1,31 +1,34 @@
 #!/usr/bin/env bash
-# This script will perform speedtests over wireguard and the
-# native connections and print their output
-#
+# This script performs speedtests over Wireguard and native connections and prints their output
 
-_speedTestData() {
-
-	local pingbps ping_f bps_f bps_int
-	export ping_int mbps_int
-
-	pingbps=$(speedtest-cli --no-upload --csv "$@" | cut -d"," -f7-8)
-	ping_f="${pingbps%,*}" # grab first value
-	ping_int="${ping_f%.*}" # make integer
-	bps_f="${pingbps#*,}" # grab second value
-	bps_int="${bps_f%.*}" # make integer
-	mbps_int=$((bps_int / 1000000)) # convert to mbps
+run_test() {
+    local output pingBps pingPart bpsPart bpsInt
+    # Run speedtest-cli and extract the 7th and 8th CSV fields
+    output=$(speedtest-cli --no-upload --csv "$@" 2>/dev/null) || return 1
+    pingBps=$(echo "$output" | cut -d"," -f7-8)
+    
+    # Extract ping value (as an integer) and bps (and convert to Mbps)
+    pingPart="${pingBps%,*}"
+    bpsPart="${pingBps#*,}"
+    pingInt="${pingPart%.*}"
+    bpsInt="${bpsPart%.*}"
+    mbpsInt=$(( bpsInt / 1000000 ))
+    
+    echo "$pingInt $mbpsInt"
 }
 
 # Test Wireguard using automatic server selection
-if _speedTestData; then
-	echo "Wireguard:"
-	echo -e "\tPing: $ping_int"
-	echo -e "\tMbps: $mbps_int"
+if output=$(run_test); then
+    read -r pingInt mbpsInt <<< "$output"
+    echo "Wireguard:"
+    echo -e "\tPing: $pingInt"
+    echo -e "\tMbps: $mbpsInt"
 fi
 
 # Test native connection to ISP
-if _speedTestData --server 17170; then
-	echo "Native:"
-	echo -e "\tPing: $ping_int"
-	echo -e "\tMbps: $mbps_int"
-fi
+if output=$(run_test --server 17170); then
+    read -r pingInt mbpsInt <<< "$output"
+    echo "Native:"
+    echo -e "\tPing: $pingInt"
+    echo -e "\tMbps: $mbpsInt"
+fi

+ 0 - 31
shell/ssh-colorize

@@ -1,31 +0,0 @@
-#!/usr/bin/env bash
-
-if [[ -n $SSH_CLIENT ]]; then
-  case $HOSTNAME in
-    *.example.com) prompt_user_host_color='1;35';; # magenta on example.com
-    *) prompt_user_host_color='1;33';; # yellow elsewhere
-  esac
-else
-  unset prompt_user_host_color;; # omitted on the local machine
-fi
-if [[ -n $prompt_user_host_color ]]; then
-  PS1='\[\e['$prompt_user_host_color'm\]\u@\h'
-else
-  PS1=
-fi
-PS1+='\[\e[1;34m\] \w\[\e[1;31m\]$(__git_ps1)\[\e[1;0;37m\] \$\[\e[0m\] '
-
-if [[ -n $SSH_CLIENT ]]; then
-  case $HOSTNAME in
-    *.example.com) prompt_user_host_color='1;35';; # magenta on example.com
-    *) prompt_user_host_color='1;33';; # yellow elsewhere
-  esac
-else
-  unset prompt_user_host_color;; # omitted on the local machine
-fi
-if [[ -n $prompt_user_host_color ]]; then
-  PS1='\[\e['$prompt_user_host_color'm\]\u@\h'
-else
-  PS1=
-fi
-PS1+='\[\e[1;34m\] \w\[\e[1;31m\]$(__git_ps1)\[\e[1;0;37m\] \$\[\e[0m\] '

+ 20 - 21
shell/ssh-wrap

@@ -1,5 +1,4 @@
 #!/usr/bin/env bash
-
 # Usage: ./ssh-wrap user@host
 
 # Capture SSH output
@@ -10,29 +9,29 @@ echo "$output"
 
 # Check if the known_hosts warning appears
 if echo "$output" | grep -q "REMOTE HOST IDENTIFICATION HAS CHANGED"; then
-    echo "It appears the host key has changed or a man-in-the-middle attack is possible."
+  echo "It appears the host key has changed or a man-in-the-middle attack is possible."
 
-    # Extract the known_hosts file and line number from the "Offending RSA key in ..." line
-    # The line format typically is: "Offending RSA key in /path/to/known_hosts:line"
-    # We'll use awk to split by ':' and space to grab the file and line number
-    if offending_info=$(echo "$output" | grep "Offending RSA key in"); then
-        KNOWN_HOSTS_FILE=$(echo "$offending_info" | awk '{print $5}' | cut -d: -f1)
-        LINE_NUMBER=$(echo "$offending_info" | awk -F: '{print $NF}')
+  # Extract the known_hosts file and line number from the "Offending RSA key in ..." line
+  # The line format typically is: "Offending RSA key in /path/to/known_hosts:line"
+  # We'll use awk to split by ':' and space to grab the file and line number
+  if offending_info=$(echo "$output" | grep "Offending RSA key in"); then
+    KNOWN_HOSTS_FILE=$(echo "$offending_info" | awk '{print $5}' | cut -d: -f1)
+    LINE_NUMBER=$(echo "$offending_info" | awk -F: '{print $NF}')
 
-        echo "Offending key detected in: $KNOWN_HOSTS_FILE on line: $LINE_NUMBER"
-        read -p "Would you like to remove this offending key line and re-attempt the SSH connection? [y/N]: " RESPONSE
-        if [[ "$RESPONSE" =~ ^[Yy]$ ]]; then
-            # Backup known_hosts
-            cp "$KNOWN_HOSTS_FILE" "$KNOWN_HOSTS_FILE.bak"
-            # Remove offending line
-            sed -i "${LINE_NUMBER}d" "$KNOWN_HOSTS_FILE"
-            echo "Offending key removed. Retrying SSH connection..."
-            ssh "$@"
-        else
-            echo "Key was not removed. Exiting."
-        fi
+    echo "Offending key detected in: $KNOWN_HOSTS_FILE on line: $LINE_NUMBER"
+    read -rp "Remove offending key and re-attempt the SSH connection? [y/N]: " RESPONSE
+    if [[ "$RESPONSE" =~ ^[Yy]$ ]]; then
+      # Backup known_hosts
+      cp "$KNOWN_HOSTS_FILE" "$KNOWN_HOSTS_FILE.bak"
+      # Remove offending line
+      sed -i "${LINE_NUMBER}d" "$KNOWN_HOSTS_FILE"
+      echo "Offending key removed. Retrying SSH connection..."
+      ssh "$@"
     else
-        echo "Could not extract offending key information. Remove it manually if needed."
+      echo "Key was not removed. Exiting."
     fi
+  else
+    echo "Could not extract offending key information. Remove it manually if needed."
+  fi
 fi
 

+ 4 - 3
shell/tmux-management

@@ -1,7 +1,8 @@
 #!/usr/bin/env bash
-# tmux‑management2 – open a tiled tmux window with one pane per host.
-# Each pane attaches to (or creates) a tmux session called $REMOTE_SESSION
-# on the target host.  The local host is always the *last* (active) pane.
+# Open a tiled tmux window with one pane per host each in its own tmux session
+# The local host is always the last (active) pane.
+# Copyright 2021-2025 Bryan C. Roessler
+# Licensed under the Apache License, Version 2.0
 
 set -euo pipefail
 

+ 0 - 145
shell/toolbox-run

@@ -1,145 +0,0 @@
-#!/usr/bin/env bash
-#
-# This program will execute commands in the specified toolbox container
-#
-# Author:
-#   Bryan Roessler
-# Source:
-#    https://git.bryanroessler.com/bryan/scripts/src/master/toolboxrun
-#
-toolboxrun () {
-
-    _printHelpAndExit () {
-
-        cat <<-'EOF'
-USAGE
-    toolboxRun -c NAME [-i NAME] [-r RELEASE] [--no-sh] [-h] [-s] [-d] [COMMANDS [ARGS...]]
-
-COMMANDS
-
-    COMMANDS to run in the container (e.g. the current active file, an external
-    build script, a program residing in the container, etc.)
-    Can be empty (default entrypoint)
-
-OPTIONS
-
-    --container NAME, -c NAME
-        Assign  a  different  NAME  to the toolbox container. This is useful for creating multiple
-        toolbox containers from the same base image, or for entirely  customized  containers  from
-        custom-built base images.
-
-        If the toolbox container NAME already exists, the command passed to toolboxRun will be
-        executed in the existing toolbox. If toolbox container NAME does not exist, it will be
-        created and the COMMAND will then be run in it.
-
-    --image NAME, -i NAME
-        Change the NAME of the base image used to create the toolbox container. This is useful for
-        creating containers from custom-built base images.
-
-    --release RELEASE, -r RELEASE
-        Create a toolbox container for a different operating system RELEASE than the host.
-
-    --ephemeral
-        The toolbox will be removed after the COMMAND is executed
-
-    --recreate
-        If the toolbox NAME already exists, it will first be removed and recreated
-
-    --no-sh, -n
-        Do not wrap COMMANDS in 'sh -c'
-
-    --help, -h
-        Print this help message and exit (overrides --silent)
-
-EOF
-
-        # Exit using passed exit code
-        [[ -z $1 ]] && exit 0 || exit "$1"
-    }
-
-
-    _parseInput () {
-
-        # Parse input and set switches using getopt
-        if _input=$(getopt -o +c:i:r:nh -l container:,image:,release:,ephemeral,recreate,no-sh,help -- "$@"); then
-            eval set -- "$_input"
-            while true; do
-                case "$1" in
-                    --container|-c)
-                        shift && export _cname="$1"
-                        ;;
-                    --image|-i)
-                        shift && export _image=("-i" "$1")
-                        ;;
-                    --release|-r)
-                        shift && export _release=("-r" "$1")
-                        ;;
-                    --ephemeral)
-                        export _ephemeral="true"
-                        ;;
-                    --recreate)
-                        export _recreate="true"
-                        ;;
-                    --no-sh|-n)
-                        export _no_sh="true"
-                        ;;
-                    --help|-h)
-                        _printHelpAndExit 0
-                        ;;
-                    --)
-                        shift
-                        break
-                        ;;
-                esac
-                shift
-            done
-        else
-            echo "Incorrect options provided"
-            _printHelpAndExit 1
-        fi
-
-        # Create _pre_commands_array from remaining arguments
-        # shift getopt parameters away
-        shift $((OPTIND - 1))
-        # Assume program name is first argument
-        export _program="$1"
-        # create command array
-        declare -ga _cmd_array=("$@")
-    }
-
-
-    _shWrap () { [[ -z $_no_sh ]] && _cmd_array=("sh" "-c" "${_cmd_array[*]}"); }
-    _toolboxExists () { toolbox list -c | cut -d ' ' -f 3 | grep -w "$1" > /dev/null 2>&1; }
-    _toolboxCreate () { toolbox create -c "$1" "${_image[@]}" "${_release[@]}"; }
-    _toolboxRemove () { toolbox rm -f "$1"; }
-    _toolboxRun () { toolbox run -c "$1" "${_cmd_array[@]}"; }
-
-
-    __main () {
-
-        # Get input
-        _parseInput "$@"
-        # Wrap command with `sh -c` by default
-        [[ -z $_no_sh ]] && _shWrap
-        # Check if container exists
-        if _toolboxExists "$_cname"; then
-            if [[ -n $_recreate || -n $_ephemeral ]]; then
-                _toolboxRemove "$_cname"
-            fi
-        else
-            _toolboxCreate "$_cname"
-        fi
-
-        _toolboxRun "$_cname" && export _ec="$?"
-
-        [[ -n $_ephemeral ]] && _toolboxRemove "$_cname"
-    }
-
-    # Allow this function to be executed directly
-    __main "$@"
-}
-
-if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
-    toolboxrun "$@"
-    exit 0
-fi

+ 0 - 47
systemd/autologin@.service

@@ -1,47 +0,0 @@
-#  This file is part of systemd.
-#
-#  systemd is free software; you can redistribute it and/or modify it
-#  under the terms of the GNU Lesser General Public License as published by
-#  the Free Software Foundation; either version 2.1 of the License, or
-#  (at your option) any later version.
-
-[Unit]
-Description=Getty on %I
-Documentation=man:agetty(8) man:systemd-getty-generator(8)
-Documentation=http://0pointer.de/blog/projects/serial-console.html
-After=systemd-user-sessions.service plymouth-quit-wait.service
-After=rc-local.service
-
-# If additional gettys are spawned during boot then we should make
-# sure that this is synchronized before getty.target, even though
-# getty.target didn't actually pull it in.
-Before=getty.target
-IgnoreOnIsolate=yes
-
-# On systems without virtual consoles, don't start any getty. Note
-# that serial gettys are covered by serial-getty@.service, not this
-# unit.
-ConditionPathExists=/dev/tty0
-
-[Service]
-# the VT is cleared by TTYVTDisallocate
-ExecStart=-/sbin/agetty --noclear -a %I $TERM
-Type=idle
-Restart=always
-RestartSec=0
-UtmpIdentifier=%I
-TTYPath=/dev/%I
-TTYReset=yes
-TTYVHangup=yes
-TTYVTDisallocate=yes
-KillMode=process
-IgnoreSIGPIPE=no
-SendSIGHUP=yes
-
-# Unset locale for the console getty since the console has problems
-# displaying some internationalized messages.
-Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION=
-
-[Install]
-WantedBy=getty.target
-DefaultInstance=tty1

+ 0 - 14
systemd/battery-charge-thresholds.service

@@ -1,14 +0,0 @@
-[Unit]
-Description=Set battery charge thresholds
-After=multi-user.target
-StartLimitBurst=0
-
-[Service]
-Type=oneshot
-Restart=on-failure
-RemainAfterExit=yes
-ExecStart=/bin/bash -c 'echo 80 > /sys/class/power_supply/BAT0/charge_control_start_threshold; echo 90 > /sys/class/power_supply/BAT0/charge_control_end_threshold'
-ExecStop=/bin/bash -c 'echo 100 > /sys/class/power_supply/BAT0/charge_control_end_threshold; echo 99 > /sys/class/power_supply/BAT0/charge_control_start_threshold'
-
-[Install]
-WantedBy=multi-user.target