Cách đơn giản nhất là định kỳ sync một thư mục local với một thư mục remote, thí dụ Google Drive, hay ngược lại. Việc này rclone làm tốt, script chỉ định kỳ làm việc qua crontab mà không cần giám sát sự thay đổi trong thư mục, áp dụng cho rất nhiều loại ổ đĩa đám mây.
#!/bin/bash
# Script cloudsync, sync to cloud drive, version 20220510
# © 2019 LNT <lnt@ly-le.info>
#
LOG="$HOME/$(basename $0).log"
SYM="Do not use the -L and -z options at the same time"
function usage(){
cat >&2 <<EOF
usage: $(basename $0) [-a age][-c][-x file|folder/][-L|-z][-P] SRC_DIR DST_DIR
-a age: only sync files/directories created/changed no later than this age
age has the suffix ms|s|m|h|d|w|M|y
-c : copy instead of sync
-L : copy the destination directory of the symbolic link
-z : copy the symlinks into a DST_DIR/symlink.tgz archive
without -L and -z option, skip symlinks
-x : Exclude relative file|folder from SRC_DIR, eg. '-x file -x folder/'
-P : print copy progress
SRC_DIR, DST_DIR: local|remote folder
EOF
[ $# -ge 2 ] && date +"%Y-%m-%d %T $1!" | tee -a "$LOG"
exit 2
}
FROM_DIR='';TO_DIR=''
z_flag=0
cmd='sync'
OPT=('--transfers=20' '--checkers=100' '--tpslimit=20' '--drive-acknowledge-abuse' '--fast-list' '-v' '-u')
EXC=()
while getopts :a:x:o:czLP opt; do
case $opt in
a) [[ "$OPTARG" =~ [0-9]+(ms|[smhdwMy]) ]] && OPT+=("--max-age=$OPTARG") || usage "Time is not in the correct format!"
;;
c) cmd='copy'
;;
L) (($z_flag)) && usage $SYM || OPT+=('--copy-links')
;;
P) OPT+=('-P')
;;
x) EXC+=("$OPTARG")
;;
o) [ ! "$LOG" = "$OPTARG" ] && { cat "$LOG" >> "$OPTARG";rm -f "$LOG";LOG="$OPTARG"; }
;;
z) [[ "${OPT[*]}" = *'--copy-links'* ]] && usage $SYM || z_flag=1
;;
?) usage
;;
esac
done
shift $(( $OPTIND-1 ))
[ $# -ne 2 ] && usage "SRC_DIR or DST_DIR is invalid!"
SRC_DIR="$1"
sDir="${SRC_DIR#*:}"
DST_DIR="$2"
if ((${#EXC[@]})); then
for p in "${EXC[@]}"; do
p=${p#"$sDir"}
[ ${p: -1} = '/' ] && OPT+=("--exclude=$p**") || OPT+=("--exclude=$p")
done
fi
if [[ ! -z "$sDir" && ! "${sDir: -1}" = '/' ]]; then
tDir=$(basename "$sDir")
dDir=${DST_DIR#*:}
[[ -z "$dDir" || "$dDir" = *'/' ]] && DST_DIR="$DST_DIR$tDir" || DST_DIR="$DST_DIR/$tDir"
fi
tmp=''
if (( $z_flag )); then
slnk=$(find "$SRC_DIR" -type l -exec test -e {} \; -print)
[ ! -z "$slnk" ] && { tmp=$(mktemp); tar -czf $tmp $slnk &> /dev/null; }
[ -s "$tmp" ] || z_flag=0
fi
if ! ps ax | grep -v grep | grep "rclone $cmd $SRC_DIR" &> /dev/null; then
OPT+=("--log-file=$LOG")
date +"%Y-%m-%d %T rclone $cmd \"$SRC_DIR\" \"$DST_DIR\" ${OPT[*]}" | tee -a $LOG
rclone $cmd $SRC_DIR $DST_DIR ${OPT[*]}
(( $z_flag )) && { rclone copyto $tmp $DST_DIR/symlink.tgz ${OPT[*]}; rm -f $tmp; }
else
date +"%Y-%m-%d %T cloudsync is working... Exit!" | tee -a $LOG
fi
Chú thích
Gỉa sử thư mục cục bộ là /path/to/local và thư mục remote là remote:folder
Cài đặt mỗi 15 phút sync với ổ đĩa đám mây, thí dụ Google Drive, trong crontab như sau
*/15 * * * * /path/to/cloudsync /path/to/local remote:folder
Để lấy file từ ổ đĩa đám mây, viết lại câu lệnh
/path/to/cloudsync remote:folder /path/to/local
- Với symbolic link có 3 cách xử lý: sao chép nội dung mà chúng trỏ tới (option -L), nén các symlink trong một file tar (option -z), hoặc bỏ qua (mặc định)
- Để bỏ qua (option -x) không làm việc với thư mục con của nguồn, thí dụ /path/to/local/sub và /path/to/local, chỉ cần ghi đường dẫn tương đối của thư mục con so với nguồn, thí dụ -x sub/
Thư mục luôn kết thúc với / để phân biệt với file - Nếu nguồn kết thúc với /, nội dung của nguồn được sao chép: /path/to/local/ => remote:folder
- Nếu nguồn không kết thúc với /, thư mục con của nguồn được sao chép: /path/to/local => remote:folder/local
- Áp dụng cho mọi ổ đĩa đám mây mà rclone hỗ trợ
- Với dữ liệu khá lớn, thí dụ 100GB, thời gian kiểm tra/đồng bộ mất hơn 10 phút. Vì vậy phải chỉnh crontab cho hợp lý.
- Giả sử định kỳ backup ngày 1 lần, chúng ta có thể đặt option -a 24h dặn rclone chỉ backup những file/thư mục được tạo/thay đổi trong 24 giờ trở lại thôi, giúp giảm đáng kể thời gian làm việc.
cloudsync -a 24h /path/to/local remote:folder