This is a follow up on this question. Most comments have been addressed or were not applicable. Feel free to point out any bad practice. My comments on the previous review:
Command chaining and subprocesses: Is it a good coding practice to bunch up commands in a subshells just to chain them ?
echo "$1" | ts is unsafe: Can you please clarify why ?
Git isn't a backup system / DB should not be in git: if I lose the DB, I lose my backups because I don't know by heart the FTP accesses to get them back(nor the encryption key). Hence sending the DB somewhere it is always accessible. And in case there is a local data corruption followed by a synch/backup, having it in a VCS guarantees I can recover. Is there a better way to do this ?
#!/bin/bash
# Compares local and remote copies of the keepass db. If there are any diff, the local replaces remote, as local is the
# master.
# KeepassXC tends to make some meta-data changes (DB preferences, last opened group...)
# which will be picked up by this script. Therefore, a sync might happen even if no entry has been
# added/modified/deleted
#
# This script is run weekly by anacron (see ~/.anacron/cron.weekly). Output is sent by mail if MAIL_TO is defined
# in anacrontab.
# It requires:
# - ts (apt install moreutils) for timestamps in the logs
#
# It should be placed in the bin directory of the user so that it automatically appears in $PATH
#
# Usage:
# backupKeepassDB.sh
log () {
echo "$1" | ts '[%F %H:%M:%.S]' 2>&1 | tee -a "$log_file"
}
clone_remote_repo () {
( cd "$temp_dir" 2>> "$log_file" &&
log "INFO - Cloning remote repo" &&
git clone [email protected]:notfound/notfound.git 2>> "$log_file" ) ||
( log "ERROR - Failed to clone remote repository" && false )
}
update_and_push () {
( rm "$remote_keepassdb_file" 2>> "$log_file" &&
cp "$local_keepassdb_file" "$local_repository_dir" 2>> "$log_file" ) ||
( log "ERROR - Failed to remove $remote_keepassdb_file or copy $local_keepassdb_file to $local_repository_dir" && false )
( cd "$local_repository_dir" 2>> "$log_file" &&
git add . 2>> "$log_file" &&
git commit -m "Update from $HOSTNAME" 2>> "$log_file" &&
git push origin main 2>> "$log_file" ) ||
( log "ERROR - Failed to push remote repository" && false )
}
cleanup() {
( [ -d "$temp_dir" ] && rm -rf "$temp_dir" ) || log "WARN - Failed to clean up temp directory"
}
check_files_are_readable () {
[ -r "$local_keepassdb_file" ] || ( log "ERROR - $local_keepassdb_file not found or not readable" && false )
[ -r "$remote_keepassdb_file" ] || ( log "ERROR - $remote_keepassdb_file not found or not readable" && false )
}
trap cleanup EXIT
temp_dir=$(mktemp -d)
log_file="$HOME/Logs/backupkeepassdb.log"
local_keepassdb_file="$HOME/Documents/Secret/Passwords/KeepassXC/Passwords.kdbx"
local_repository_dir="$temp_dir/backup"
remote_keepassdb_file="$local_repository_dir/Passwords.kdbx"
repo_identity_file="$HOME/.ssh/notfoundToGitlab_id_ed25519"
export GIT_SSH_COMMAND="SSH_AUTH_SOCK='/run/user/1000/keyring/ssh' ssh -i $repo_identity_file -o IdentitiesOnly=yes -F /dev/null"
log "INFO - Starting Password db backup"
clone_remote_repo || ( echo "ERROR - Clone failed." && exit 1 )
check_files_are_readable || ( log "Either or both DB are not readable" && exit 1 )
cmp "$local_keepassdb_file" "$remote_keepassdb_file" &&
log "INFO - Local Keepass DB and Remote Keepass DB are identical. No update needed" &&
exit 0
( log "INFO - DB files are different. Updating remote..." &&
update_and_push &&
log "INFO - Remote has been updated." ) || exit 1