Skip to content

Instantly share code, notes, and snippets.

@guicaulada
Created December 29, 2025 06:54
Show Gist options
  • Select an option

  • Save guicaulada/34f7b10d69059200815066342eb770e3 to your computer and use it in GitHub Desktop.

Select an option

Save guicaulada/34f7b10d69059200815066342eb770e3 to your computer and use it in GitHub Desktop.
Cryptomator Backup script
#!/usr/bin/env bash
# Usage:
# ./backup_script.sh encrypt <input_folder1> [input_folder2 ...] [output_file]
# ./backup_script.sh decrypt <input_file> [output_dir]
#
# Examples:
# ./backup_script.sh encrypt FINANCE/ RECOVERY/ 202512290317-BACKUP.tar.gz.gpg
# ./backup_script.sh decrypt 202512290317-BACKUP.tar.gz.gpg
#
# Requirements: gpg, tar, op (1Password CLI) installed and configured.
# Replace 'op://your-vault/your-item/password' with your actual 1Password item path.
if [ $# -lt 2 ]; then
echo "Usage: $0 {encrypt|decrypt} <input(s)> [output]"
exit 1
fi
action="$1"
shift # Shift to make inputs start at $1
# Your 1Password passphrase path (update this)
passphrase_path="op://your-vault/your-item/password"
# Fetch passphrase securely
passphrase=$(op read "$passphrase_path")
if [ -z "$passphrase" ]; then
echo "Error: Failed to read passphrase from 1Password."
exit 1
fi
case "$action" in
encrypt)
# Determine if last arg is output (check if it ends with .tar.gz.gpg)
if [[ "${!#}" =~ \.tar\.gz\.gpg$ ]]; then
output="${!#}"
inputs=("${@:1:$#-1}")
else
inputs=("$@")
output=""
fi
# Check inputs are directories (at least one)
if [ ${#inputs[@]} -eq 0 ]; then
echo "Error: No input directories specified."
exit 1
fi
for dir in "${inputs[@]}"; do
if [ ! -d "$dir" ]; then
echo "Error: Input '$dir' is not a directory."
exit 1
fi
done
# Default output if not provided
if [ -z "$output" ]; then
timestamp=$(date +%Y%m%d%H%M)
if [ ${#inputs[@]} -eq 1 ]; then
# Single folder: use full name
base_name=$(basename "${inputs[0]}")
output="${timestamp}-${base_name}.tar.gz.gpg"
else
# Multiple folders: use initials
initials=""
for dir in "${inputs[@]}"; do
base=$(basename "$dir")
initial=${base:0:1}
initials="${initials}${initial^^}" # Uppercase the initial
done
output="${timestamp}-${initials}.tar.gz.gpg"
fi
fi
echo "Encrypting ${inputs[*]} to '$output'..."
tar -czf - "${inputs[@]}" | gpg --batch --pinentry-mode loopback --symmetric --cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-count 65000000 --passphrase "$passphrase" -o "$output"
if [ $? -eq 0 ]; then
echo "Encryption complete: $output"
else
echo "Encryption failed."
exit 1
fi
;;
decrypt)
input="$1"
output="${2:-}" # Optional output dir
if [ ! -f "$input" ]; then
echo "Error: Input '$input' is not a file."
exit 1
fi
# Default output dir: strip .tar.gz.gpg from input
if [ -z "$output" ]; then
output="${input%.tar.gz.gpg}"
fi
mkdir -p "$output"
echo "Decrypting '$input' to '$output'..."
gpg --batch --pinentry-mode loopback -d --passphrase "$passphrase" "$input" | tar -xzf - -C "$output"
if [ $? -eq 0 ]; then
echo "Decryption complete: $output"
else
echo "Decryption failed."
exit 1
fi
;;
*)
echo "Invalid action: $action. Use 'encrypt' or 'decrypt'."
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment