#!/usr/bin/env bash # borg-browser.sh — fzf-based Borg archive browser with passphrase prompt [ "$EUID" -ne 0 ] && { echo "Please run as root."; exec sudo "$0" "$@"; } REPO="/holocron/backups" # Prompt once for Borg passphrase read -rs -p "Borg passphrase: " BORG_PASSPHRASE echo export BORG_PASSPHRASE # Pick an archive ARCHIVE=$(borg list --short "$REPO" | fzf --prompt="Select archive: ") || { unset BORG_PASSPHRASE exit } [ -z "$ARCHIVE" ] && { unset BORG_PASSPHRASE; exit; } # Function to browse directories hierarchically browse_borg_dir() { local prefix="$1" while true; do # Get immediate children of the current path ITEMS=$(borg list --format='{path}{NL}' "$REPO::$ARCHIVE" \ | awk -v p="$prefix" -F/ ' BEGIN{n=split(p,a,"/")} index($0,p)==1 && NF>n { if (NF==n+1) print $NF; else print $(n+1)"/"; }' \ | sort -u) [ -z "$ITEMS" ] && { echo "No items found in $prefix"; return; } SELECTION=$(echo -e "../\n$ITEMS" | fzf --prompt="${prefix:-/}> ") case "$SELECTION" in "../") prefix="${prefix%/*}" prefix="${prefix%/}" ;; "") return ;; */) prefix="${prefix:+$prefix/}${SELECTION%/}" ;; *) local fullpath="${prefix:+$prefix/}$SELECTION" echo "Selected file: $fullpath" read -rp "Extract it here? [y/N]: " yn if [[ $yn =~ ^[Yy]$ ]]; then borg extract "$REPO::$ARCHIVE" "$fullpath" fi return ;; esac done } browse_borg_dir "" unset BORG_PASSPHRASE