Compare commits

..

No commits in common. "fa7b4d89eee3e9fa8d0d56388f3e725d4954f9c8" and "d2662598bbee103dfa8bde875d48f5e4bf3c529f" have entirely different histories.

4 changed files with 49 additions and 116 deletions

View File

@ -1,16 +1,15 @@
# Maintainer: Matthias Quintern <matthiasqui@protonmail.com> # Maintainer: Matthias Quintern <matthiasqui@protonmail.com>
pkgname=msynk pkgname=msynk
pkgver=1.3 pkgver=1.1
pkgrel=2 pkgrel=1
pkgdesc="rsync helper that supports encryption (through mkrypt) and presets" pkgdesc="rsync helper that supports encryption and presets"
arch=('any') arch=('any')
url="https:/github.com/MatthiasQuintern/msynk" url="https:/github.com/MatthiasQuintern/msynk"
license=('GPL3') license=('GPL3')
depends=('rsync') depends=('rsync')
optdepends=('mkrypt: for encryption') optdepends=('mkrypt: for encryption')
source=(msynk.sh _msynk.compdef.zsh msynk.1.man template) source=(msynk.sh _msynk.compdef.zsh msynk.1.man template)
md5sums=(4392e5545877c02d673370326ea130e5 515d71a5e9be5a26a5921dddf6509d9d d089828a93bf8e4ffd9051d8ea756ab8 492028aa2f08528f1d476376884959b2) md5sums=(d22b062903a9fcd1bd9508cbd06cbc6c d089828a93bf8e4ffd9051d8ea756ab8 8398678146d9f8a5669e8b788502b3b8 492028aa2f08528f1d476376884959b2)
package() { package() {
mkdir -p "${pkgdir}/usr/bin" mkdir -p "${pkgdir}/usr/bin"

View File

@ -22,7 +22,6 @@ _msynk()
{--sender,-s}'[Sender directory, with trailing "/".]':directory:_directories \ {--sender,-s}'[Sender directory, with trailing "/".]':directory:_directories \
{--receiver,-r}'[Receiver directory, with trailing "/".]':directory:_directories \ {--receiver,-r}'[Receiver directory, with trailing "/".]':directory:_directories \
'--reverse[Swap receiver and sender.]' \ '--reverse[Swap receiver and sender.]' \
{--relative,-R}'[User relative path names.]' \
'--encrypt[Encrypt files before syncing.]' \ '--encrypt[Encrypt files before syncing.]' \
'--decrypt[Decrypt files before syncing.]' \ '--decrypt[Decrypt files before syncing.]' \
'--check-date[Only process files that have been modified since the program was last run. Needs -c and (--encrypt/--decrypt).]' \ '--check-date[Only process files that have been modified since the program was last run. Needs -c and (--encrypt/--decrypt).]' \

142
msynk.sh
View File

@ -9,25 +9,21 @@
# SETTINGS # SETTINGS
# The directory that is searched for config files, use ~/.config if $XDG_CONFIG_HOME is not defined # The directory that is searched for config files, use ~/.config if $XDG_CONFIG_HOME is not defined
CONFIG_DIR=~/.config/msynk [[ -z $XDG_CONFIG_HOME ]] && XDG_CONFIG_HOME=~/.config
[[ -n $XDG_CONFIG_HOME ]] && CONFIG_DIR=$XDG_CONFIG_HOME/msynk CONFIG_DIR=$XDG_CONFIG_HOME/msynk/
[[ -n $MSYNK_CONFIG_HOME ]] && CONFIG_DIR=$MSYNK_CONFIG_HOME # When using encrypt/decrypt, the source is en/decrypted to TMP_DIR and then rsynced to receiver from there
# YOU CAN OVERRIDE THESE IN THE CONFIG FILES
# When using encrypt/decrypt, the source is en/decrypted to TMP_DIR and then rsynced to receiver from there Path must contain 'msynk' TMP_DIR=/tmp/msynk/ When using --delete, this file is used to determine the files that will be deleted TMP_FILE=/tmp/msynk_file Path to the mkrypt script mkrypt=/usr/bin/mkrypt
# Path must contain 'msynk' # Path must contain 'msynk'
TMP_DIR=/tmp/msynk/ TMP_DIR=/tmp/msynk/
# When using --delete, this file is used to determine the files that will be deleted # When using --delete, this file is used to determine the files that will be deleted
TMP_FILE=/tmp/msynk_file TMP_FILE=/tmp/msynk_file
# Path to the mkrypt script # Path to the mkrypt script
mkrypt=/usr/bin/mkrypt mkrypt=/usr/bin/mkrypt
# Additional flags for mkrypt # Additional flags for mkrypt
mkrypt_flags=() mkrypt_flags=()
rsync_flags=(-ruh) rsync_flags=(-ruh)
# rsync_flags+=(--rsh="ssh -p 22") # rsync_flags+=(--rsh="ssh -p 42")
# r - recursive # r - relative
# v - verbose # v - verbose
# Ut - preserve modification&access times # Ut - preserve modification&access times
# u - update, skip files that are newer on the receiver # u - update, skip files that are newer on the receiver
@ -39,13 +35,12 @@ rsync_flags=(-ruh)
shopt -s dotglob shopt -s dotglob
# UTILITY # UTILITY
NAME="\e[1;34mmsynk" FMT_MESSAGE="\e[1;34m%s\e[0m %s\n"
FMT_MESSAGE="$NAME: \e[0;34m%s\e[0m %s\n" FMT_ERROR="\e[1;31mmsync ERROR: \e[0m%s\n"
FMT_ERROR="\e[1;31m$NAME: \e[1;31mERROR: \e[0m%s\n"
# exit 1: error, exit 2: rsync exited non 0, exit 3: mkrypt exited non 0 # exit 1: error, exit 2: rsync exited non 0, exit 3: mkrypt exited non 0
FMT_SYNC="$NAME: \e[1;32mSyncing: \e[0m%s\n" FMT_SYNC="\e[1;32mSyncing: \e[0m%s\n"
FMT_CMD="$NAME: \e[1;33mRunning: \e[0m%s\n"
FMT_CONFIG="\e[34m%s\e:\t\e[1;33m%s\e[0m\n" FMT_CONFIG="\e[34m%s\e:\t\e[1;33m%s\e[0m\n"
FMT_CMD="\e[1;33mRunning: \e[0m%s\n"
# FUNCTIONS # FUNCTIONS
# silence commands # silence commands
@ -75,27 +70,6 @@ check_path_in_args()
} }
_sync_set_dest() {
if [[ -d "$path" ]]; then
if [[ -n "$relative" ]]; then
dest="$receiver"
else
dest="$receiver"$(basename "$path")
fi
elif [[ -f $path ]]; then
dest="$receiver"
elif [[ "$sender" == *:* ]]; then # if sender is remote, assume the path is a dir if it has a slash and a file otherwise
if [[ "$path" == *\/ ]]; then
dest="$receiver"$(basename "$path")
else
dest="$receiver"
fi
else
printf "$FMT_ERROR" "Invalid path: $path"; exit 1
fi
}
# SYNC SENDER TO RECEIVER # SYNC SENDER TO RECEIVER
sync_sender_to_receiver() sync_sender_to_receiver()
{ {
@ -104,59 +78,38 @@ sync_sender_to_receiver()
[[ $v -ge 1 ]] && printf "$FMT_MESSAGE" "Performing dryrun" "to generate list of files that will be deleted from $receiver..." [[ $v -ge 1 ]] && printf "$FMT_MESSAGE" "Performing dryrun" "to generate list of files that will be deleted from $receiver..."
echo "" > $TMP_FILE echo "" > $TMP_FILE
for path in "${filtered_paths[@]}"; do for path in "${filtered_paths[@]}"; do
_sync_set_dest dest_subdir=$receiver$(basename $path)
# if [ -n $relative ]; then rsync $rsync_flags -v --dry-run --delete $path $dest_subdir | grep deleting | sed "s(deleting (${BACKUP_SUBDIR}/(" >> $TMP_FILE
# dest_subdir="$receiver"
# else
# dest_subdir="$receiver"$(basename "$path")
# fi
[[ $v -ge 3 ]] && printf "$FMT_CMD" "rsync ${rsync_flags[*]} -v --dry-run --delete $path $dest | grep deleting | sed \"s(deleting (${BACKUP_SUBDIR}/(\" >> $TMP_FILE"
rsync "${rsync_flags[@]}" -v --dry-run --delete $path $dest | grep deleting | sed "s(deleting (${BACKUP_SUBDIR}/(" >> $TMP_FILE
done done
# print files that will be deleted and ask if continue # print files that will be deleted and ask if continue
# grep deleting $TMP_FILE | sed "s(deleting (${receiver}/(" | less # grep deleting $TMP_FILE | sed "s(deleting (${receiver}/(" | less
less $TMP_FILE less $TMP_FILE
DONE=0
while [[ $DONE == 0 ]]; do printf "$FMT_MESSAGE" "The listed files will be deleted from $receiver."
printf "$FMT_MESSAGE" "The listed files will be deleted from $receiver." printf "Proceed?\e[34m (y/n)\e[0m: "
printf "Proceed?\e[34m ([y]es, [s]how again, [*] no)\e[0m: " read answer
# printf "Proceed?\e[34m ([y]es, [s]how again, [l]ist all files, [*] no)\e[0m: " case $answer in
read answer y|Y)
case $answer in # printf "$FMT_MESSAGE" "Backing up to $receiver..."
y|Y) ;;
DONE=1 *)
;; printf "$FMT_MESSAGE" "Cancelled."
s|S) exit 0 ;;
less $TMP_FILE esac
;;
# l|L)
# less $TMP_FILE
# ;;
*)
printf "$FMT_MESSAGE" "Cancelled."
exit 0 ;;
esac
done
fi fi
# actual syncing # actual syncing
for path in "${filtered_paths[@]}"; do for path in "${filtered_paths[@]}"; do
[[ $v -ge 1 ]] && printf "$FMT_SYNC" "$path" [[ $v -ge 1 ]] && printf "$FMT_SYNC" "$path"
_sync_set_dest if [[ -d "$path" ]]; then
#if [[ -d "$path" ]]; then dest="$receiver"$(basename "$path")
# if [[ -n "$relative" ]]; then elif [[ -f $path ]]; then
# dest="$receiver" dest="$receiver"
# else elif [[ "$sender" == *:* ]]; then # if sender is remote, assume the path is a dir if it has a slash and a file otherwise
# dest="$receiver"$(basename "$path") [[ "$path" == *"/" ]] && dest="$receiver"$(basename "$path") || dest="$receiver"
# fi else
#elif [[ -f $path ]]; then printf "$FMT_ERROR" "Invalid path: $path"; exit 1
# dest="$receiver" fi
#elif [[ "$sender" == *:* ]]; then # if sender is remote, assume the path is a dir if it has a slash and a file otherwise
# #[[ "$path" == *"/" ]] && dest="$receiver"$(basename "$path") || dest="$receiver"
# dest=$receiver
#else
# printf "$FMT_ERROR" "Invalid path: $path"; exit 1
#fi
if [[ -n $encrypt || -n $decrypt ]]; then if [[ -n $encrypt || -n $decrypt ]]; then
mkdir -p "$TMP_DIR" mkdir -p "$TMP_DIR"
tmp_source="$TMP_DIR" tmp_source="$TMP_DIR"
@ -164,7 +117,7 @@ sync_sender_to_receiver()
if [[ -n $encrypt ]]; then if [[ -n $encrypt ]]; then
# check if TMP_DIR has enough space # check if TMP_DIR has enough space
tmp_free=$(df --output=avail $TMP_DIR | grep -E "[[:digit:]]+") tmp_free=$(df --output=avail $TMP_DIR | grep -E "[[:digit:]]+")
path_size=$(du -s "$path" | awk '{print $1}' | sed -e "s/[^0-9]//g") path_size=$(du -s "$path" | sed -e "s/[^0-9]//g")
if [[ $tmp_free -le $path_size ]]; then if [[ $tmp_free -le $path_size ]]; then
printf "$FMT_ERROR" "Not enough space on $TMP_DIR to copy $path! $TMP_DIR $tmp_free free - Size $path: $path_size" printf "$FMT_ERROR" "Not enough space on $TMP_DIR to copy $path! $TMP_DIR $tmp_free free - Size $path: $path_size"
printf "$FMT_MESSAGE" "" "If using a tmpfs, you can increase its size by running: 'sudo mount -o remount,size=XXG,noatime /tmp' to increase the size to XXG (You will need a large enough swap space)" printf "$FMT_MESSAGE" "" "If using a tmpfs, you can increase its size by running: 'sudo mount -o remount,size=XXG,noatime /tmp' to increase the size to XXG (You will need a large enough swap space)"
@ -194,12 +147,12 @@ sync_sender_to_receiver()
# put todays date in the config # put todays date in the config
if [[ -f $CONFIG_DIR/$config ]]; then if [[ -f $CONFIG_DIR/$config ]]; then
if grep -xq "date=.*" $CONFIG_DIR/$config; then if grep -xq "date=.*" $CONFIG_DIR$config; then
[[ $v -ge 2 ]] && printf "$FMT_MESSAGE" "Updating" "date in $CONFIG_DIR/$config." [[ $v -ge 2 ]] && printf "$FMT_MESSAGE" "Updating" "date in $CONFIG_DIR$config."
sed "s/date=.*/date=\"$(date --iso=sec)\"/" $CONFIG_DIR/$config -i sed "s/date=.*/date=\"$(date --iso=sec)\"/" $CONFIG_DIR$config -i
else else
[[ $v -ge 2 ]] && printf "$FMT_MESSAGE" "Writing" "current date to $CONFIG_DIR/$config." [[ $v -ge 2 ]] && printf "$FMT_MESSAGE" "Writing" "current date to $CONFIG_DIR$config."
echo "date=\"$(date --iso=sec)\"" >> $CONFIG_DIR/$config echo "date=\"$(date --iso=sec)\"" >> $CONFIG_DIR$config
fi fi
fi fi
@ -261,9 +214,9 @@ show_settings()
show_config() show_config()
{ {
[[ ! -f $CONFIG_DIR/$config ]] && { printf "$FMT_ERROR" "Invalid path: $CONFIG_DIR/$config"; exit 1; } [[ ! -f $CONFIG_DIR$config ]] && { printf "$FMT_ERROR" "Invalid path: $CONFIG_DIR$config"; exit 1; }
source $CONFIG_DIR/$config source $CONFIG_DIR$config
printf "\e[1m$CONFIG_DIR/$config:\e[0m\n" printf "\e[1m$CONFIG_DIR$config:\e[0m\n"
printf "$FMT_CONFIG" "\$sender " "$sender" printf "$FMT_CONFIG" "\$sender " "$sender"
printf "$FMT_CONFIG" "\$receiver " "$receiver" printf "$FMT_CONFIG" "\$receiver " "$receiver"
printf "$FMT_CONFIG" "\$paths " "${paths[*]}" printf "$FMT_CONFIG" "\$paths " "${paths[*]}"
@ -279,7 +232,6 @@ fi
all=1 all=1
paths_2=() paths_2=()
v=1 # verbosity
while (( "$#" )); do while (( "$#" )); do
case "$1" in case "$1" in
-h|--help) -h|--help)
@ -356,9 +308,6 @@ while (( "$#" )); do
--exclude) --exclude)
exclude=1 exclude=1
shift ;; shift ;;
-R|--relative)
relative=1
shift ;;
-*|--*=) # unsupported flags -*|--*=) # unsupported flags
printf "$FMT_ERROR" "Unsupported flag $1" >&2 printf "$FMT_ERROR" "Unsupported flag $1" >&2
exit 1 ;; exit 1 ;;
@ -387,11 +336,11 @@ fi
# if using a config # if using a config
if [[ -n $config ]]; then if [[ -n $config ]]; then
source $CONFIG_DIR/$config || { printf "$FMT_ERROR" "Error running the config file: $CONFIG_DIR/$config"; exit 1; } source $CONFIG_DIR$config || { printf "$FMT_ERROR" "Error running the config file: $CONFIG_DIR$config"; exit 1; }
if [[ $use_encryption = 1 ]]; then if [[ $use_encryption = 1 ]]; then
[[ -z $reverse ]] && encrypt=1 || decrypt=1 [[ -z $reverse ]] && encrypt=1 || decrypt=1
fi fi
[[ $v -ge 3 ]] && printf "$FMT_MESSAGE" "Loaded config:" "$CONFIG_DIR/$config: date:$date sender:$sender receiver:$receiver use_encryption:$use_encryption encrypt:$encrypt decrypt:$decrypt paths:${paths[*]}" [[ $v -ge 3 ]] && printf "$FMT_MESSAGE" "Loaded config:" "$CONFIG_DIR$config: date:$date sender:$sender receiver:$receiver use_encryption:$use_encryption encrypt:$encrypt decrypt:$decrypt paths:${paths[*]}"
fi fi
# overwrite stuff from the config if anything else was given / set variables of no config was given # overwrite stuff from the config if anything else was given / set variables of no config was given
@ -440,11 +389,6 @@ fi
[[ $v -ge 3 ]] && printf "$FMT_MESSAGE" "Filtered paths:" "${filtered_paths[*]}" [[ $v -ge 3 ]] && printf "$FMT_MESSAGE" "Filtered paths:" "${filtered_paths[*]}"
IFS=$ifs IFS=$ifs
# apply correct base flags
if [[ -n $relative ]]; then
rsync_flags+=(--relative)
fi
# sanity checks # sanity checks
[[ -z $filtered_paths ]] && { printf "$FMT_ERROR" "Missing valid paths."; exit 1; } [[ -z $filtered_paths ]] && { printf "$FMT_ERROR" "Missing valid paths."; exit 1; }
[[ -z $receiver ]] && { printf "$FMT_ERROR" "Missing receiver. Specifiy with --receiver"; exit 1; } [[ -z $receiver ]] && { printf "$FMT_ERROR" "Missing receiver. Specifiy with --receiver"; exit 1; }

View File

@ -1,6 +1,6 @@
# msynk - rsync helper that supports encryption and presets # msynk - rsync helper that supports encryption and presets
## Description ## DESCRIPTION
**msynk** uses *rsync* to synchronise files or directories locally or between devices. **msynk** uses *rsync* to synchronise files or directories locally or between devices.
In general, you should always add a trailing '/' to directories. In general, you should always add a trailing '/' to directories.
@ -29,7 +29,7 @@ To sync the directories "/home/user/foo" "/home/user/bar" and the file "/home/us
``` ```
You can then run this with: `msynk -c my_backup`, or if you only want to sync the "foo" directory and ".txt" files: `msynk -c my_backup foo .txt` You can then run this with: `msynk -c my_backup`, or if you only want to sync the "foo" directory and ".txt" files: `msynk -c my_backup foo .txt`
## Options ## OPTIONS
- `-h, --help` Show a list of arguments. - `-h, --help` Show a list of arguments.
- `--settings` Show the current settings. - `--settings` Show the current settings.
- `-c, --config config-name` Retrieve settings from config file ~/.config/msynk/*config-name* - `-c, --config config-name` Retrieve settings from config file ~/.config/msynk/*config-name*
@ -37,7 +37,6 @@ You can then run this with: `msynk -c my_backup`, or if you only want to sync th
- `-s, --sender path` Set sender to directory. This can also be a remote, like user@domain.com:/dir. Defaults to to the current working directory. - `-s, --sender path` Set sender to directory. This can also be a remote, like user@domain.com:/dir. Defaults to to the current working directory.
- `-r, --receiver path` Set the receiver directory. All files and directories will be placed inside this directory. This can also be a remote, like user@domain.com:/dir. This option always needs to be set. Note that this directory must already exist if it is on a remote. - `-r, --receiver path` Set the receiver directory. All files and directories will be placed inside this directory. This can also be a remote, like user@domain.com:/dir. This option always needs to be set. Note that this directory must already exist if it is on a remote.
- `--reverse` Swaps sender and receiver. Useful when you want to reverse a config file. - `--reverse` Swaps sender and receiver. Useful when you want to reverse a config file.
- `-R, --relative` Use relative path names, uses *rsync* --relative option instead of --recursive
- `--encrypt` Encrypt files with *mkrypt* before sending them to the receiver. The files are encrypted to $TMP_DIR and then synced to the receiver. Does not work with --delete. - `--encrypt` Encrypt files with *mkrypt* before sending them to the receiver. The files are encrypted to $TMP_DIR and then synced to the receiver. Does not work with --delete.
- `--decrypt` Decrypt files with *mkrypt* after receiving them from the sender. Assumes that all files are encrypted and fails if that is not the case. The files are synced to $TMP_DIR and then decrypted to the receiver directory. Does not work with --delete. - `--decrypt` Decrypt files with *mkrypt* after receiving them from the sender. Assumes that all files are encrypted and fails if that is not the case. The files are synced to $TMP_DIR and then decrypted to the receiver directory. Does not work with --delete.
- `--check-date` Can be used with -c and --encrypt or --decrypt: When running msynk with a config, the current date is stored in the config file. When running with --check-date, only files that have been modified after the date stored in the config file are processed (by passing--date [date the config was last run] to *mkrypt*). - `--check-date` Can be used with -c and --encrypt or --decrypt: When running msynk with a config, the current date is stored in the config file. When running with --check-date, only files that have been modified after the date stored in the config file are processed (by passing--date [date the config was last run] to *mkrypt*).
@ -58,14 +57,6 @@ The $TMP_DIR defaults to /tmp/mksynk and /tmp is usually limited to half the siz
You change the $TMP_DIR in the script in /usr/bin/msynk or temporarily increase the size of the tmpfs by running `sudo mount -o remount,size=XXG,noatime /tmp` if your $TMP_DIR is on /tmp and you have at least XXGB memory+swap space. You change the $TMP_DIR in the script in /usr/bin/msynk or temporarily increase the size of the tmpfs by running `sudo mount -o remount,size=XXG,noatime /tmp` if your $TMP_DIR is on /tmp and you have at least XXGB memory+swap space.
## Changelog ## Changelog
### 1.3
- Added relative path support
### 1.2
Bugfixes:
- rsync_flags are now applied to dryrun
- disk usage is correctly obtained for paths with numbers in them
### 1.1 ### 1.1
- Added --exclude - Added --exclude