cloudsync: Sync với cloud drive (I)

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

Comments Off on cloudsync: Sync với cloud drive (I)

Filed under Software

Comments are closed.