Last active
June 18, 2021 16:04
-
-
Save m-rey/65c0656ccf5fcb859c0260e6798ef110 to your computer and use it in GitHub Desktop.
function to bulk merge KeepassXC DBs (*.kdbx)
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
#!/bin/sh | |
# DESCRIPTION | |
# Merge one or more KeepassXc DBs into another KeepassXC DB. | |
# | |
# PURPOSE | |
# Syncthing can't natively merge/rebase KeepassXC DB files (yet?), thus it sometimes | |
# falls back to saving all differing DB versions as file sync conflicts. | |
# Luckily, `keepassxc-cli` *can* merge one DB into another, but only one at a time. | |
# As Syncthing often creates many conflict files, it would take ages to manually merge | |
# each DB. That's what `merge_kdbx` aims to solve: | |
# It's a wrapper for `keepassxc-cli` that implements merging many DBs into one. | |
# | |
# USAGE | |
# merge_kdbx target_db_file source_db_file [source_db_file2...] | |
# | |
# EXAMPLES | |
# merge_kdbx pw.kdbx pw.*conflict*.kdbx | |
# merge_kdbx pw.kdbx pw.*.kdbx <<< 'YOUR PASSWORD HERE' | |
# merge_kdbx pw.kdbx pw.*.kdbx <<< 'YOUR PASSWORD HERE' >merge.out.log 2>merge.err.log | |
# | |
# BACKUPS | |
# The script creates a backup dir for each bulk merge, | |
# containing a copy of the target DB before each individual merge. | |
# The generated backup dir is located in the same dir as the target DB, for ease of use. | |
# | |
# ASSUMPTIONS | |
# As the primary use case for this script is to merge almost identical DBs, some assumptions were made: | |
# - all DBs are secured using a password # TODO: Add support for keyfiles etc | |
# - all DBs share the same password # TODO: try to read pw from env var if set; TODO: add support for multiple pw? | |
# - your goal is to one-way-merge DB modifications back into the same DB. Once that's done, the other DBs can be deleted | |
# - you won't enter anything into the terminal, if it is still going through the `merge_kdbx` script. TODO: fix hacky pw input by using `expect` instead? | |
function merge_kdbx () { | |
if [ $# -lt 2 ]; then | |
echo "Error: Illegal number of passed databases. Please provide a merge target and at least one merge source." | |
exit 64 | |
fi | |
target_db="$1" | |
shift | |
source_dbs=("$@") | |
printf 'Enter password of target db "%s":\n' "$target_db" | |
read -rs TARGET_DB_PASSWORD | |
# create a new time-stamped backup dir each time this *function* is executed to later save a backup after every individual merge in it | |
backup_dir_target_db="$(mktemp --directory --tmpdir="$(readlink -f "$target_db" | xargs dirname)" "$(date -u +"%Y-%m-%dT%H-%M-%S")_BACKUP_$(basename "$target_db"_XXXXXX)")" | |
for source_db in "${source_dbs[@]}"; do | |
# create empty, uniquely backup file | |
backup_target_db="$(mktemp --tmpdir="$backup_dir_target_db" "$(basename "$target_db")~before~$(basename "$source_db")~XXXXXX.bak")" | |
# copy db to empty backup file and print result | |
printf 'Creating backup: %s\n' "$(cp --verbose "$target_db" "$backup_target_db")" | |
printf 'Merging database "%s" into "%s":\n' "$source_db" "$target_db" | |
# it's expected that all databases use the same credentials, as they are most likely sync conflicts | |
keepassxc-cli merge --same-credentials "$target_db" "$source_db" <<<"$TARGET_DB_PASSWORD" | |
done | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment