Created
December 29, 2025 06:54
-
-
Save guicaulada/34f7b10d69059200815066342eb770e3 to your computer and use it in GitHub Desktop.
Cryptomator Backup script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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