備份 macOS 中的家目錄到 AWS S3 中


由於一些特殊的需求,必須把資料備份到 AWS S3,又踩了一些 awscli 的雷,再來紀錄一下XD

一開始我直接用 aws s3 sync ~/ s3://xxx --delete,配合 --exclude 來排除一些軟體的資料夾,例如 ~/Library~/Application這些不重要的資料,但發現 awscli 的 --exclude 有一點問題,他仍然會讀取到已經排除的資料夾,花了非常多的時間在掃這些用不到的資料:

warning: Skipping file "xxx" File does not exist. 

爬到相關文章「aws s3 sync warning: Skipping file “.” File does not exist. #1082」,測了一下還是一樣沒有用,後來決定捨棄他的排除,用我們的老牌 Rsync 啦!

使用 Rsync 輔助 AWS CLI

非常簡單,把要排除的檔案、資料夾先寫在 Rsync 的 --excloude 來處理,awscli 只需要推備份的資料夾到 S3 就可以了,下面的 Script 還有加了一些基本的網路狀況判斷與 Log 的部分:

#!/bin/sh
RSYNC=/usr/bin/rsync
AWS=/usr/local/bin/aws
NC=/usr/bin/nc
MKDIR=/bin/mkdir
TEE=/usr/bin/tee
# brew install moreutils
TS=/opt/homebrew/bin/ts


SOURCE=~/
S3_BUCKET="mybackup-s3"
RSYNC_TEMP=".s3"

function upload(){
    $MKDIR -p ~/$RSYNC_TEMP
    $RSYNC -avh \
        --exclude '.Trash' \
        --exclude '.DS_Store' \
        --exclude '.cache' \
        --exclude '.socket' \
        --exclude 'Applications' \
        --exclude 'OneDrive' \
        --exclude 'Library' \
        --exclude $RSYNC_TEMP \
        $SOURCE ~/$RSYNC_TEMP/ \
        --delete
    $AWS s3 sync ~/$RSYNC_TEMP/ s3://$S3_BUCKET --delete
}
function main(){
    echo "Checking Network Connection.."
    if $NC -zw1 google.com 443; then
        upload
    fi
}
main 2>&1 | $TS '[%Y-%m-%d %H:%M:%S]' | $TEE -a ~/backup.log

S3 的其他指令可以參考更詳細的官方文件,其實滿簡單的:透過 AWS CLI 使用高階 (s3) 命令 - 同步物件

加入 Crontab

因為 macOS 的權限限制,必須把這些軟體允許存取硬碟:

  • /usr/sbin/cron
  • /usr/bin/crontab
  • /usr/bin/rsync

到系統設定 Settings -> Security & Privacy -> Privacy -> Full Disk Access,左下角解除鎖頭後,點一下「+」,按下 「Command+Shift+G 」,再依序輸入上述的路徑允許以允許「Full Disk Access」,這樣子就可以順利自動備份了了


See also

comments powered by Disqus