2 Commity 7ed56cf4fd ... af725302ba

Autor SHA1 Wiadomość Data
  Bryan Roessler af725302ba Update scripts 3 tygodni temu
  Bryan Roessler dfb1c230cc Update scripts and move dotfiles 3 tygodni temu

+ 0 - 2
.gitignore

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

+ 0 - 1
dotfiles/.gitignore

@@ -1 +0,0 @@
-secrets/

+ 0 - 245
dotfiles/btrbk/.config/btrbk/btrbk.conf

@@ -1,245 +0,0 @@
-#
-# Example btrbk configuration file
-#
-#
-# Please refer to the btrbk.conf(5) man-page for a complete
-# description of all configuration options.
-# For more examples, see README.md included with this package.
-#
-#   btrbk.conf(5): <https://digint.ch/btrbk/doc/btrbk.conf.5.html>
-#   README.md:     <https://digint.ch/btrbk/doc/readme.html>
-#
-# Note that the options can be overridden per volume/subvolume/target
-# in the corresponding sections.
-#
-
-
-# Enable transaction log
-transaction_log            /var/log/btrbk.log
-
-# Specify SSH private key for remote connections
-ssh_identity               /home/bryan/.config/btrbk/id_ed25519
-ssh_user                   root
-
-# Use sudo if btrbk or lsbtr is run by regular user
-backend_local_user         btrfs-progs-sudo
-
-# Enable stream buffer. Adding a buffer between the sending and
-# receiving side is generally a good idea.
-# NOTE: If enabled, make sure to install the "mbuffer" package!
-stream_buffer              1g
-
-# Directory in which the btrfs snapshots are created. Relative to
-# <volume-directory> of the volume section.
-# If not set, the snapshots are created in <volume-directory>.
-#
-# If you want to set a custom name for the snapshot (and backups),
-# use the "snapshot_name" option within the subvolume section.
-#
-# NOTE: btrbk does not automatically create this directory, and the
-# snapshot creation will fail if it is not present.
-#
-snapshot_dir               .snapshots
-
-# Always create snapshots. Set this to "ondemand" to only create
-# snapshots if the target volume is reachable. Set this to "no" if
-# snapshot creation is done by another instance of btrbk.
-snapshot_create            onchange
-
-# Perform incremental backups (set to "strict" if you want to prevent
-# creation of non-incremental backups if no parent is found).
-#incremental                yes
-
-# Specify after what time (in full hours after midnight) backups/
-# snapshots are considered as a daily backup/snapshot
-#preserve_hour_of_day       0
-
-# Specify on which day of week weekly/monthly backups are to be
-# preserved.
-#preserve_day_of_week       sunday
-
-# Preserve all snapshots for a minimum period of time.
-#snapshot_preserve_min      1d
-
-# Retention policy for the source snapshots.
-#snapshot_preserve          <NN>h <NN>d <NN>w <NN>m <NN>y
-
-# Preserve all backup targets for a minimum period of time.
-#target_preserve_min        no
-
-# Retention policy for backup targets:
-#target_preserve            <NN>h <NN>d <NN>w <NN>m <NN>y
-
-# Retention policy for archives ("btrbk archive" command):
-#archive_preserve_min       no
-#archive_preserve           <NN>h <NN>d <NN>w <NN>m <NN>y
-
-# Enable compression for remote btrfs send/receive operations:
-#stream_compress            no
-#stream_compress_level      default
-#stream_compress_threads    default
-
-# Enable lock file support: Ensures that only one instance of btrbk
-# can be run at a time.
-lockfile                   /var/lock/btrbk.lock
-
-# Don't wait for transaction commit on deletion. Enable this to make
-# sure the deletion of subvolumes is committed to disk when btrbk
-# terminates.
-#btrfs_commit_delete no
-
-
-#
-# Volume section (optional): "volume <volume-directory>"
-#
-#   <volume-directory>  Base path within a btrfs filesystem
-#                       containing the subvolumes to be backuped
-#                       (usually the mount-point of a btrfs filesystem
-#                       mounted with subvolid=5 option).
-#
-# Subvolume section: "subvolume <subvolume-name>"
-#
-#   <subvolume-name>    Subvolume to be backuped, relative to
-#                       <volume-directory> in volume section.
-#
-# Target section: "target <type> <volume-directory>"
-#
-#   <type>              (optional) type, defaults to "send-receive".
-#   <volume-directory>  Directory within a btrfs filesystem
-#                       receiving the backups.
-#
-# NOTE: The parser does not care about indentation, this is only for
-# human readability. All options apply to the last section
-# encountered, overriding the corresponding option of the upper
-# section. This means that the global options must be set on top,
-# before any "volume", "subvolume" or "target section.
-#
-
-#
-# Example retention policy:
-#
-# snapshot_preserve_min   2d
-# snapshot_preserve       14d
-# target_preserve_min     no
-# target_preserve         20d 10w *m
-
-snapshot_preserve_min   2d
-snapshot_preserve       14d
-
-target_preserve_min     no
-target_preserve         14d 10w *m
-
-archive_preserve_min    latest
-archive_preserve        12m 10y
-
-# Global settings
-compat_remote busybox
-send_protocol 2
-
-# Root backup workaround, omit the volume section
-subvolume /
-  target_preserve 14d 10w 6m
-  snapshot_dir /.snapshots # Absolute path to snapshots dir
-  target /mnt/backup/workstation/root
-  # target ssh://router.lan/mnt/backup/workstation/root
-# target /run/media/bryan/backup/workstation/root
-# target ssh://home-router/mnt/backup/workstation/root
-
-volume /home
-  subvolume bryan
-    target /mnt/backup/workstation/home
-    # target ssh://router.lan/mnt/backup/workstation/home
-    target_preserve 14d 10w 6m
-    # target ssh://home-router/mnt/backup/workstation/home
-    # target /run/media/bryan/backup/workstation/home
-
-volume /mnt/downloads
-  subvolume downloads
-    target /mnt/backup/workstation/downloads
-    # target /run/media/bryan/backup/workstation/downloads
-
-#volume /mnt/array/media
-#  target /mnt/backup/media
-  # target ssh://router.lan/mnt/backup/media
-#  target ssh://home-router/mnt/backup/media
-#  subvolume music
-#    target_preserve_min all # for home-router to keep samba share (and safer overall)
-#  subvolume ebooks
-#  subvolume pictures
-
-# #
-# # Simple setup: Backup root and home to external disk
-# #
-# snapshot_dir /btrbk_snapshots
-# target       /mnt/btr_backup
-# subvolume    /
-# subvolume    /home
-
-
-# #
-# # Complex setup
-# #
-# # In order to keep things organized, it is recommended to use "volume"
-# # sections and mount the top-level subvolume (subvolid=5):
-# #
-# #  $ mount -o subvolid=5 /dev/sda1 /mnt/btr_pool
-# #
-# # Backup to external disk mounted on /mnt/btr_backup
-# volume /mnt/btr_pool
-#   # Create snapshots in /mnt/btr_pool/btrbk_snapshots
-#   snapshot_dir btrbk_snapshots
-
-#   # Target for all subvolume sections:
-#   target /mnt/btr_backup
-
-#   # Some default btrfs installations (e.g. Ubuntu) use "@" for rootfs
-#   # (mounted at "/") and "@home" (mounted at "/home"). Note that this
-#   # is only a naming convention.
-#   #subvolume @
-#   subvolume root
-#   subvolume home
-#   subvolume kvm
-#     # Use different retention policy for kvm backups:
-#     target_preserve 7d 4w
-
-
-# # Backup data to external disk as well as remote host
-# volume /mnt/btr_data
-#   subvolume  data
-#     # Always create snapshot, even if targets are unreachable
-#     snapshot_create always
-#     target /mnt/btr_backup
-#     target ssh://backup.my-remote-host.com/mnt/btr_backup
-
-
-# # Backup from remote host, with different naming
-# volume ssh://my-remote-host.com/mnt/btr_pool
-#   subvolume data_0
-#     snapshot_dir   snapshots/btrbk
-#     snapshot_name  data_main
-#     target /mnt/btr_backup/my-remote-host.com
-
-
-# # Backup on demand (noauto) to remote host running busybox, login as
-# # regular user using ssh-agent with current user name (ssh_user no)
-# # and default credentials (ssh_identity no).
-# volume /home
-#   noauto  yes
-#   compat  busybox
-#   backend_remote  btrfs-progs-sudo
-#   ssh_user      no
-#   ssh_identity  no
-
-#   target ssh://my-user-host.com/mnt/btr_backup/home
-#   subvolume  alice
-#   subvolume  bob
-
-
-# # Resume backups from remote host which runs its own btrbk instance
-# # creating snapshots for "home" in "/mnt/btr_pool/btrbk_snapshots".
-# volume ssh://my-remote-host.com/mnt/btr_pool
-#   snapshot_dir           btrbk_snapshots
-#   snapshot_create        no
-#   snapshot_preserve_min  all
-#   subvolume home
-#     target /mnt/btr_backup/my-remote-host.com

+ 0 - 24
dotfiles/deploy

@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-# Deploys the dotfiles in this directory using GNU stow
-set -euo pipefail
-
-# Get this script's directory
-SCRIPT_DIR=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
-
-# Change to the dotfiles directory (push current dir on the stack)
-pushd "$SCRIPT_DIR" > /dev/null || exit 1
-
-# Loop through non-hidden top-level dirs and stow them
-for dir in */; do
-  [[ $dir == .* || $dir == secrets/ ]] && continue  # Skip dot-directories
-  echo "Stowing $dir"
-  if ! stow "$dir"; then
-    errorcode=$?
-    echo "Error stowing $dir"
-  fi
-done
-
-# Return to original directory
-popd > /dev/null || exit 1
-
-exit "${errorcode:-0}"

+ 0 - 8
dotfiles/git/.gitconfig

@@ -1,8 +0,0 @@
-# This is Git's per-user configuration file.
-[user]
-	email = bryanroessler@gmail.com
-	name = Bryan Roessler
-[color]
-	ui = auto
-[credential]
-	helper = cache

+ 0 - 31
dotfiles/tmux/.tmux.conf

@@ -1,31 +0,0 @@
-# Synchronize windows shortcut
-unbind a
-bind a set-window-option synchronize-panes
-
-# Use | and - to split a window vertically and horizontally instead of " and % respoectively
-unbind '"'
-unbind %
-bind | split-window -h -c "#{pane_current_path}"
-bind - split-window -v -c "#{pane_current_path}"
-
-# Automatically set window title
-set-window-option -g automatic-rename on
-set-option -g set-titles on
-
-# Use r to quickly reload tmux settings
-unbind r
-bind r \
-	source-file ~/.tmux.conf \;\
-	display 'Reloaded tmux config'
-
-# Set the history limit so we get lots of scrollback.
-setw -g history-limit 50000000
-
-# switch panes using Alt-arrow without prefix
-bind -n M-Left select-pane -L
-bind -n M-Right select-pane -R
-bind -n M-Up select-pane -U
-bind -n M-Down select-pane -D
-
-# Enable mouse mode
-set -g mouse on

+ 0 - 169
dotfiles/vim/.vimrc

@@ -1,169 +0,0 @@
-" File: .vimrc
-" Author: Jake Zimmerman <jake@zimmerman.io>
-"
-" How I configure Vim :P
-"
-
-" Gotta be first
-set nocompatible
-
-filetype off
-
-set rtp+=~/.vim/bundle/Vundle.vim
-call vundle#begin()
-
-Plugin 'VundleVim/Vundle.vim'
-
-" ----- Making Vim look good ------------------------------------------
-Plugin 'altercation/vim-colors-solarized'
-Plugin 'tomasr/molokai'
-Plugin 'vim-airline/vim-airline'
-Plugin 'vim-airline/vim-airline-themes'
-
-" ----- Vim as a programmer's text editor -----------------------------
-Plugin 'scrooloose/nerdtree'
-Plugin 'jistr/vim-nerdtree-tabs'
-Plugin 'vim-syntastic/syntastic'
-Plugin 'xolox/vim-misc'
-Plugin 'xolox/vim-easytags'
-Plugin 'majutsushi/tagbar'
-Plugin 'ctrlpvim/ctrlp.vim'
-Plugin 'vim-scripts/a.vim'
-
-" ----- Working with Git ----------------------------------------------
-Plugin 'airblade/vim-gitgutter'
-Plugin 'tpope/vim-fugitive'
-
-" ----- Other text editing features -----------------------------------
-Plugin 'Raimondi/delimitMate'
-
-" ----- man pages, tmux -----------------------------------------------
-Plugin 'jez/vim-superman'
-Plugin 'christoomey/vim-tmux-navigator'
-
-" ----- Syntax plugins ------------------------------------------------
-Plugin 'jez/vim-c0'
-Plugin 'jez/vim-ispc'
-Plugin 'kchmck/vim-coffee-script'
-
-" ---- Extras/Advanced plugins ----------------------------------------
-" Highlight and strip trailing whitespace
-"Plugin 'ntpeters/vim-better-whitespace'
-" Easily surround chunks of text
-"Plugin 'tpope/vim-surround'
-" Align CSV files at commas, align Markdown tables, and more
-"Plugin 'godlygeek/tabular'
-" Automaticall insert the closing HTML tag
-"Plugin 'HTML-AutoCloseTag'
-" Make tmux look like vim-airline (read README for extra instructions)
-"Plugin 'edkolev/tmuxline.vim'
-" All the other syntax plugins I use
-"Plugin 'ekalinin/Dockerfile.vim'
-"Plugin 'digitaltoad/vim-jade'
-"Plugin 'tpope/vim-liquid'
-"Plugin 'cakebaker/scss-syntax.vim'
-
-call vundle#end()
-
-filetype plugin indent on
-
-" --- General settings ---
-set backspace=indent,eol,start
-set ruler
-set number
-set showcmd
-set incsearch
-set hlsearch
-
-syntax on
-
-set mouse=a
-
-" We need this for plugins like Syntastic and vim-gitgutter which put symbols
-" in the sign column.
-hi clear SignColumn
-
-" ----- Plugin-Specific Settings --------------------------------------
-
-" ----- altercation/vim-colors-solarized settings -----
-" Toggle this to "light" for light colorscheme
-set background=dark
-
-" Uncomment the next line if your terminal is not configured for solarized
-let g:solarized_termcolors=256
-
-" Set the colorscheme
-colorscheme solarized
-
-
-" ----- bling/vim-airline settings -----
-" Always show statusbar
-set laststatus=2
-
-" Fancy arrow symbols, requires a patched font
-" To install a patched font, run over to
-"     https://github.com/abertsch/Menlo-for-Powerline
-" download all the .ttf files, double-click on them and click "Install"
-" Finally, uncomment the next line
-"let g:airline_powerline_fonts = 1
-
-" Show PASTE if in paste mode
-let g:airline_detect_paste=1
-
-" Show airline for tabs too
-let g:airline#extensions#tabline#enabled = 1
-
-" Use the solarized theme for the Airline status bar
-let g:airline_theme='solarized'
-
-" ----- jistr/vim-nerdtree-tabs -----
-" Open/close NERDTree Tabs with \t
-nmap <silent> <leader>t :NERDTreeTabsToggle<CR>
-" To have NERDTree always open on startup
-let g:nerdtree_tabs_open_on_console_startup = 1
-
-" ----- scrooloose/syntastic settings -----
-let g:syntastic_error_symbol = '✘'
-let g:syntastic_warning_symbol = "▲"
-augroup mySyntastic
-  au!
-  au FileType tex let b:syntastic_mode = "passive"
-augroup END
-
-
-" ----- xolox/vim-easytags settings -----
-" Where to look for tags files
-set tags=./tags;,~/.vimtags
-" Sensible defaults
-let g:easytags_events = ['BufReadPost', 'BufWritePost']
-let g:easytags_async = 1
-let g:easytags_dynamic_files = 2
-let g:easytags_resolve_links = 1
-let g:easytags_suppress_ctags_warning = 1
-
-" ----- majutsushi/tagbar settings -----
-" Open/close tagbar with \b
-nmap <silent> <leader>b :TagbarToggle<CR>
-" Uncomment to open tagbar automatically whenever possible
-"autocmd BufEnter * nested :call tagbar#autoopen(0)
-
-
-" ----- airblade/vim-gitgutter settings -----
-" In vim-airline, only display "hunks" if the diff is non-zero
-let g:airline#extensions#hunks#non_zero_only = 1
-
-
-" ----- Raimondi/delimitMate settings -----
-let delimitMate_expand_cr = 1
-augroup mydelimitMate
-  au!
-  au FileType markdown let b:delimitMate_nesting_quotes = ["`"]
-  au FileType tex let b:delimitMate_quotes = ""
-  au FileType tex let b:delimitMate_matchpairs = "(:),[:],{:},`:'"
-  au FileType python let b:delimitMate_nesting_quotes = ['"', "'"]
-augroup END
-
-" ----- jez/vim-superman settings -----
-" better man page support
-noremap K :SuperMan <cword><CR>
-

+ 0 - 133
dotfiles/zsh/.zshrc

@@ -1,133 +0,0 @@
-# Shell options
-setopt autocd correct globdots extendedglob nomatch notify \
-  share_history inc_append_history hist_expire_dups_first hist_reduce_blanks \
-  hist_find_no_dups hist_verify extended_history auto_pushd pushd_ignore_dups \
-  prompt_subst
-unsetopt beep
-bindkey -e
-
-# Load secrets
-if [[ -f .env ]]; then
-  set -a # automatically export all variables
-  source .env
-  set +a
-fi
-
-# Completions
-local compdump=${XDG_CACHE_HOME:-$HOME/.cache}/zsh/zcompdump-${HOST}-${ZSH_VERSION}
-[[ -d ${compdump:h} ]] || mkdir -p ${compdump:h}
-zstyle ':completion:*' menu select
-zstyle ':completion:*' gain-privileges 1
-zstyle ':completion:*:descriptions' format '%U%B%d%b%u'
-zmodload zsh/complist
-autoload -Uz compinit && compinit -d "$compdump"
-
-# History
-HISTFILE=${XDG_STATE_HOME:-$HOME}/.histfile
-[[ -d $HISTFILE:h ]] || mkdir -p $HISTFILE:h
-HISTSIZE=1000000
-SAVEHIST=1000000
-autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
-zle -N up-line-or-beginning-search
-zle -N down-line-or-beginning-search
-
-# Colors
-autoload -Uz colors && colors
-
-# Prompt
-if [[ $EUID -eq 0 ]]; then
-  user_color=red
-else
-  user_color=white
-fi
-
-# Assign colors based on the hostname
-if [[ -v TOOLBOX_PATH ]]; then
-  host_color=magenta
-elif [[ -v DISTROBOX_ENTER_PATH ]]; then
-  host_color=15
-else
-  case $HOSTNAME in
-    laptop)       host_color=green ;;
-    workstation)  host_color=red ;;
-    bryan-pc)     host_color=cyan ;;
-    time4vps)     host_color=blue ;;
-    racknerd)     host_color=yellow ;;
-    htpc)         host_color=214 ;;
-    hartmanlab)   host_color=magenta ;;
-    router)       host_color=blue ;;
-    ax6000)       host_color=87 ;;
-    home-router)  host_color=218 ;;
-    vm-fedora*)   host_color=57 ;;
-    *)            host_color=white ;;
-  esac
-fi
-
-_git_prompt() {
-  local br
-  if br=$(git symbolic-ref --short HEAD 2>/dev/null); then
-    print -n " %F{242}($br)%f"
-  fi
-}
-
-PROMPT='[%F{'$user_color'}%n%f@%F{'$host_color'}%m%f]%~$(_git_prompt)%(!.#.$) '
-# RPROMPT='%*' # display clock to right of screen
-precmd() { print -Pn "\e]0;%n@%m: ${PWD/#$HOME/~}\a" ; }
-
-# Set hostname on OpenWRT
-[[ -z $HOSTNAME ]] && HOSTNAME=$(noglob uci get system.@system[0].hostname 2>/dev/null)
-
-# Paths
-typeset -U path PATH
-path=(
-  $HOME/bin
-  $HOME/.local/bin
-  $HOME/documents/develop/scripts/shell
-  $path
-)
-export PATH
-export R_LIBS_USER="$HOME/R/qhtcp-workflow"
-
-# Keybindings
-typeset -g -A key
-for k v in \
-  Home khome End kend Insert kich1 Backspace kbs Delete kdch1 \
-  Up kcuu1 Down kcud1 Left kcub1 Right kcuf1 PageUp kpp PageDown knp ShiftTab kcbt; do
-  [[ -n ${terminfo[$v]} ]] && key[$k]=${terminfo[$v]}
-done
-bindkey -- ${key[Home]-}      beginning-of-line
-bindkey -- ${key[End]-}       end-of-line
-bindkey -- ${key[Insert]-}    overwrite-mode
-bindkey -- ${key[Backspace]-} backward-delete-char
-bindkey -- ${key[Delete]-}    delete-char
-bindkey -- ${key[Left]-}      backward-char
-bindkey -- ${key[Right]-}     forward-char
-bindkey -- ${key[PageUp]-}    beginning-of-buffer-or-history
-bindkey -- ${key[PageDown]-}  end-of-buffer-or-history
-bindkey -- ${key[ShiftTab]-}  reverse-menu-complete
-bindkey -- ${key[Up]-}        up-line-or-beginning-search
-bindkey -- ${key[Down]-}      down-line-or-beginning-search
-
-if (( ${+terminfo[smkx]} && ${+terminfo[rmkx]} )); then
-  autoload -Uz add-zle-hook-widget
-  zle_app_start()  { echoti smkx; }
-  zle_app_finish() { echoti rmkx; }
-  add-zle-hook-widget zle-line-init    zle_app_start
-  add-zle-hook-widget zle-line-finish  zle_app_finish
-fi
-
-# Aliases and one-liners
-alias ll='ls -lh'
-alias la='ls -A'
-alias vmd='vmd -nt'
-alias dnf-list-files='dnf repoquery -l'
-alias gedit='gnome-text-editor'
-alias xclip='xclip -selection c'
-alias pdoman='podman'
-alias workon='virtualenv-workon'
-alias git-list='git ls-tree -r HEAD --name-only'
-alias chatgpt='chatgpt --model gpt-4o'
-podman-update-images() {
-  podman images --format '{{.Repository}}' | grep -v '^<none>$' | xargs -r -L1 podman pull
-}
-buildah-prune() { buildah rm --all; }

+ 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

+ 21 - 0
shell/dotfiles-store

@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+dotfiles-store() {
+  [[ $# -lt 2 ]] && { echo "Usage: $0 <subdir> <file1> [<file2> ...]"; return 1; }
+  local subdir=$1; shift
+  local dotdir=~/develop/dotfiles
+  mkdir -p "$dotdir/$subdir"
+  for src in "$@"; do
+    local filename
+    filename=$(basename "$src")
+    local dest="$dotdir/$subdir/$filename"
+    cp -ai "$src" "$dest" || { echo "Failed to copy $src"; continue; }
+    ln -sf "$dest" "$src"
+    echo "Moved $src → $dest and linked $src → $dest"
+  done
+}
+
+# Allow this file to be executed directly if not being sourced
+if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+    dotfiles-store "$@"
+fi

+ 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

+ 28 - 0
shell/iso-to-mkv

@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+SEARCH_DIR="${1:-$(pwd)}"
+OUT_DIR="${2:-"$SEARCH_DIR/out"}"
+mkdir -p "$OUT_DIR"
+prev_season=""
+ep=1
+
+find "$SEARCH_DIR" -type f -iname '*.iso' | sort | while read -r iso; do
+  echo "$iso"
+  parent=$(basename "$(dirname "$iso")")
+  [[ $parent =~ S([0-9]+) ]] || continue
+  season=$(printf "%02d" "${BASH_REMATCH[1]}")
+
+  [[ $season != "$prev_season" ]] && { ep=1; prev_season=$season; }
+
+  ripdir="$OUT_DIR/temp/$parent"
+  mkdir -p "$ripdir" "$OUT_DIR/Season $season"
+  snap run makemkv.makemkvcon -r mkv --minlength=1800 iso:"$iso" all "$ripdir"
+
+  for mkv in "$ripdir"/*.mkv; do
+    out="$OUT_DIR/Season $season/S${season}E$(printf "%02d" "$ep").mkv"
+    ffmpeg -nostdin -hide_banner -loglevel error -i "$mkv" \
+      -map 0:v -map 0:a:m:language:eng -map 0:s:m:language:eng \
+      -c copy "$out"
+    rm "$mkv"
+    ((ep++))
+  done
+done

+ 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
 

+ 5 - 4
shell/tmux-management

@@ -1,12 +1,13 @@
 #!/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
 
 # Configuration (override with env vars if desired)
-HOSTS=(workstation laptop vm-fedora42) # hosts in pane order
+HOSTS=(workstation laptop) # hosts in pane order
 REMOTE_SESSION=${REMOTE_SESSION:-main} # tmux session on remotes
 SYNCHRONIZE=${SYNCHRONIZE:-1} # 1 = broadcast keystrokes
 INCLUDE_LOCAL=${INCLUDE_LOCAL:-1} # 0 = skip local host

+ 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