dotfiles
Seven years worth of accumulated configuration cruft
dotfiles/scripts/.local/bin/bak
Download raw file: scripts/.local/bin/bak
#!/bin/sh # Create archives of portions of my home directory and back up the # whole thing to external drives. Depends on restic and rsync. # source `which bak` && bakmnt # https://wiki.archlinux.org/title/Persistent_block_device_naming#by-label # FIXME: How portable is /dev/disk/by-label? Maybe I should use fstab # for this instead. bakmnt() { fat_opts="rw,uid=$(id -u),gid=$(id -g),fmask=137,dmask=027" sudo zpool import backup3 sudo mount /dev/disk/by-label/Backup2 /backup/backup2 sudo mount /dev/disk/by-label/KOBOeReader /backup/ereader -o "$fat_opts" -t vfat sudo mount /dev/disk/by-label/PhoneSDcard /backup/sdcard -o "$fat_opts" -t exfat-fuse } say() { printf "\033[1m==========> %s\033[m\n" "$1"; } directory_is_accessible() { if test "${1#*sftp:}" = "$1"; then [ -w "$1" ] || { echo "Directory $1 doesn't exist or isn't writable, skipping" return 1 } mount | grep "$1" >/dev/null || { echo "Disk not mounted on $1, skipping" return 1 } fi return 0 } backup_important_dir() { src="$1" dst="$HOME/archive/backups/$(basename "$src")" say "Backing up directory $1" # shellcheck disable=SC2015 [ -w "$dst" ] && [ -f "$dst/config" ] || { mkdir -p "$dst" restic -r "$dst" --insecure-no-password init } restic -r "$dst" --insecure-no-password backup "$src" } backup_home_to() { say "Backing up home directory to $1:" if directory_is_accessible "$1"; then restic -r "$1" \ --password-command "pass machines/backup_disks" \ backup "$HOME" \ --exclude-caches \ --exclude "$HOME/temporary/torrents/" \ --exclude "$HOME/.local/go" \ --exclude "$HOME/.local/quicklisp" \ --exclude "$HOME/.local/share/Trash" \ --exclude "$HOME/.local/share/julia/" \ --exclude "$HOME/.local/share/recoll/xapiandb/" \ --exclude "$HOME/.cache" else return 0 fi } # DOS filesystems are awfully picky about what characters they allow. # Add as they come up dos_strip() { echo "$1" | sed 's/://g'; } # I had thought that passing `-rlt` to rysnc should get archive-ish # functionality to the exfat partition without spitting errors about # nonexistent file permission support, however somewhere along the way # the file mod times get clobbered so we end up draining the card's # limited write lifetime with slow, redundant transfers. This # function is a workaround for that. diff_copy_when_archaic_fs() { src="$1" dst="$2" say "Copying $src to $dst" if [ -d "$src" ] && [ -w "$dst" ]; then find "$src" -type f | while read -r srcpath; do relpath="${srcpath##"$src"/}" dstpath="$dst/$(dos_strip "$relpath")" # Copy the file over iff it doesn't exist at # the destination. if [ ! -f "$dstpath" ]; then mkdir -p -v "$(dirname "$dstpath")" cp -v "$srcpath" "$dstpath" # When the source is on the archaic # file system, fix the new file's # permissions to -rw-r--r-- if mount | grep "$src" >/dev/null 2>&1; then chmod -v 644 "$dstpath" fi fi # If the destination already exists, skip it. # FIXME could be good to do primitve change # checking by comparing file size done elif [ ! -d "$src" ]; then echo "Directory $src doesn't exist, skipping" elif [ ! -w "$dst" ]; then echo "Directory $dst doesn't exist or isn't writable, skipping" fi } # If-guard allows this script to be sourced as a library by an # interactive shell or another shell script if [ "$(basename "$0")" = "bak" ] && ! (return >/dev/null 2>&1); then set -e diff_copy_when_archaic_fs "/backup/sdcard/Backups/Signal" "$HOME/archive/backups/signal" diff_copy_when_archaic_fs "/backup/sdcard/Backups/AntennaPod" "$HOME/archive/backups/antennapod" diff_copy_when_archaic_fs "$HOME/media/music" "/backup/sdcard/Music" diff_copy_when_archaic_fs "$HOME/media/audiobooks" "/backup/sdcard/Audiobooks" diff_copy_when_archaic_fs "$HOME/media/books" "/backup/ereader/personal/Books" diff_copy_when_archaic_fs "$HOME/media/papers" "/backup/ereader/personal/Papers" diff_copy_when_archaic_fs "$HOME/media/webpages" "/backup/ereader/personal/Webpages" backup_important_dir "$HOME/org" backup_important_dir "$HOME/wiki" backup_important_dir "$HOME/secrets" backup_home_to "/backup/backup1" backup_home_to "/backup/backup2" backup_home_to "/backup/backup3" fi