-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrfync
executable file
·92 lines (78 loc) · 2.68 KB
/
rfync
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/bin/bash
# WARNING
# As of 2023-04 I have moved from this to `zclone` -- a similar tool that
# targets rclone. Rclone is NOT a perfect replacement for rsync (see comments
# in `zclone` that describe the two biggest ones), but I have found that for
# my most common use cases rclone's limitations don't matter, while it is much
# faster.
# YMMV :)
set -o pipefail
# set -x
export PS4='`[[ $? == 0 ]] || echo "\e[1;31;40m($?)\e[m\n "`:.$LINENO:'
[[ -z $1 ]] && {
cat <<-EOF >&2
warning: no error checking for arguments
Usage:
cd /local/directory
THEN
rfync hostname get remote-base-dir
OR
rfync hostname put remote-base-dir
the "remote-base-dir" is just because I usually only have a few
easy-to-type directories on the remote, but I guess I could fuzzy search
*that* also...
EOF
exit 1
}
# put in whatever you want, except "--multi"
export FZF_DEFAULT_OPTS="--exact --no-sort --reverse --info=inline"
sel_l() {
[[ ${1:-} == -m ]] && {
shift
FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS --multi"
}
bindd="--bind=ctrl-d:reload(find . -type d | sort -f)"
bindf="--bind=ctrl-f:reload(find . -type f | sort -f)"
[[ $op == get ]] && find . -type d | fzf --header="select local destination"
[[ $op == put ]] && find . -type d | fzf "$bindd" "$bindf" --header="select local source files or directories; use ctrl-d/f to switch"
}
sel_r() {
[[ ${1:-} == -m ]] && {
shift
FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS --multi"
}
bindd="--bind=ctrl-d:reload(ssh $host 'cd $rembase; find . -type d' | sort -f)"
bindf="--bind=ctrl-f:reload(ssh $host 'cd $rembase; find . -type f' | sort -f)"
[[ $op == put ]] && ssh $host "cd '$rembase'; find . -type d" | fzf --header="select REMOTE destination"
[[ $op == get ]] && ssh $host "cd '$rembase'; find . -type d" | fzf "$bindd" "$bindf" --header="select REMOTE source files or directories; use ctrl-d/f to switch"
}
get() {
echo >&2 "NOTE: add '--delete' if needed"
set -x
printf "%s\n" "${rfs[@]}" | rsync -avP -r --files-from - "$host:$rembase" "$ld"
}
put() {
echo >&2 "NOTE: add '--delete' if needed"
set -x
rsync -avP -R --rsync-path="cd '$rembase' && rsync" "${lfs[@]}" "$host:$rd"
}
# my hostnames are short enough I can just type them in as arg-1
host=$1
op=$2
rembase=$3
case $op in
get )
ld=`sel_l`
[[ -z $ld ]] && exit 2
mapfile -t rfs < <(sel_r -m)
[[ -z ${rfs[0]} ]] && exit 2
get
;;
put )
rd=`sel_r`
[[ -z $rd ]] && exit 2
mapfile -t lfs < <(sel_l -m)
[[ -z ${lfs[0]} ]] && exit 2
put
;;
esac