Posts

Showing posts from September, 2025

renew ssl certs automatically and clear out expired

 Letsencrypt used to auto fix your expired certs. This no longer happens. Here's a script to do it. Flags: --delete : remove expired certs --renew: renew soon-to-expire certs (3< days) #!/bin/bash # check-certs.sh base="/etc/letsencrypt/archive" delete_mode=0 renew_mode=0 if [ "$1" == "--delete" ]; then     delete_mode=1 elif [ "$1" == "--renew" ]; then     renew_mode=1 fi # First: find all current certs in archive declare -A cert_status find "$base" -type f -name "cert*.pem" | while read cert; do     domain=$(echo "$cert" | sed -E "s|$base/([^/]+)/cert[0-9]+\.pem|\1|")     expiry=$(openssl x509 -enddate -noout -in "$cert" | cut -d= -f2)     exp_epoch=$(date -d "$expiry" +%s)     now_epoch=$(date +%s)     days_left=$(( (exp_epoch - now_epoch) / 86400 ))     echo "$domain: $expiry  ($days_left days left)"     if [ $delete_mode -eq 1 ] && [ $days_left -lt...

find deleted files

Sometimes you want to compare an archive backup drive and a target folder and see what items got  deleted in that folder. Useful if you have a flaky backup system like dropbox. #!/usr/bin/env bash # find_deleted.sh — list non-image files that exist in SOURCE but not in TARGET # usage: ./find_deleted.sh [--rsync-check] SOURCE_DIR TARGET_DIR set -euo pipefail usage() {   echo "Usage: $0 [--rsync-check] SOURCE_DIR TARGET_DIR" >&2   exit 1 } RSYNC_CHECK=0 if [ "${1:-}" = "--rsync-check" ]; then   RSYNC_CHECK=1   shift fi [ $# -eq 2 ] || usage SRC="${1%/}" DST="${2%/}" [ -d "$SRC" ] || { echo "Source not found: $SRC" >&2; exit 2; } [ -d "$DST" ] || { echo "Target not found: $DST" >&2; exit 3; } # Returns 0 if the path looks like an image, 1 otherwise. is_image_path() {   # lower-case path (Bash-only ${var,,})   local p="${1,,}"   case "$p" in     *.jpg|*.jpeg|*....

folder deduper

 If like me you have thousands of duplicate photos, you need this. it only deduplicates on md5 (identical) files, not visually similar files. It does not run inside github as that will break any coding you are doing. #!/bin/bash # dupemd5.sh — report duplicate files by MD5; dry-run move + CSV log # Safety check: do not allow running inside GitHub directories if [[ "$(pwd)" =~ [Gg]ithub ]]; then     echo "Error: refusing to run inside a GitHub directory ($(pwd))" >&2     exit 1 fi APPLY=0 if [[ "${1:-}" == "--apply" ]]; then     APPLY=1     shift fi dir="${1:-.}" declare -A seen count=0 duplicates_dir="./duplicates" csv="$duplicates_dir/duplicates_found.csv" mkdir -p "$duplicates_dir" touch "$csv" if [[ ! -s "$csv" ]]; then     echo '"item";"original";"duplicate";"target"' > "$csv" fi print_summary() {     echo "Tota...