首先將示範你如何在 Ubuntu 上安裝 rclone、建立 Google Drive remote,最後撰寫Shell Script。
安裝 rclone
1sudo apt install rclone -y1sudo apt install rclone -y代表的意思:
-
sudo:以管理員權限執行。 -
apt install rclone:從套件庫安裝 rclone。 -
-y:自動同意所有安裝提示,不需要手動按 Yes。
安裝完後 Ubuntu 會輸出一堆像是 Database、man-db、kernel upgrade 的提示,這些是系統正常的安裝訊息,與 rclone 本體無關。
開始設定 rclone
1rclone config1rclone config這會啟動互動式設定介面,讓你建立 remote。
建立新 remote
畫面問:
1n) New remote2s) Set configuration password3q) Quit config4n/s/q>1n) New remote2s) Set configuration password3q) Quit config4n/s/q>你輸入:n
代表「建立新的 remote」。
設定 remote 名稱
畫面問:
Enter name for new remote.
name>
輸入:gdrive
意思是:你把這個 rclone 連線命名成 gdrive,之後所有操作都可以用 gdrive: 指向你的 Google Drive。
選擇儲存服務類型
畫面列出一大串支援的雲端,並問:
1sudo apt install rclone -y1sudo apt install rclone -y你輸入:18
代表選擇「Google Drive」。
client_id 與 client_secret
畫面問:
1client_id>2client_secret>直接按 Enter 留空。
代表:
-
rclone 會使用官方內建的 Google OAuth client
-
好處是簡單
-
壞處是流量被限縮,不適合大量搬資料
-
不過你的用途是備份用,留空也可以正常運作
scope 權限設定
畫面問:
1Option scope.2Scope that rclone should use when requesting access from drive.3Choose a number from below, or type in your own value.4Press Enter to leave empty.5 1 / Full access all files, excluding Application Data Folder.6 \ (drive)7 2 / Read-only access to file metadata and file contents.8 \ (drive.readonly)9 / Access to files created by rclone only.10 3 | These are visible in the drive website.11 | File authorization is revoked when the user deauthorizes the app.12 \ (drive.file)13 / Allows read and write access to the Application Data folder.14 4 | This is not visible in the drive website.15 \ (drive.appfolder)16 / Allows read-only access to file metadata but17 5 | does not allow any access to read or download file content.18 \ (drive.metadata.readonly)19scope> 11Option scope.2Scope that rclone should use when requesting access from drive.3Choose a number from below, or type in your own value.4Press Enter to leave empty.5 1 / Full access all files, excluding Application Data Folder.6 \ (drive)7 2 / Read-only access to file metadata and file contents.8 \ (drive.readonly)9 / Access to files created by rclone only.10 3 | These are visible in the drive website.11 | File authorization is revoked when the user deauthorizes the app.12 \ (drive.file)13 / Allows read and write access to the Application Data folder.14 4 | This is not visible in the drive website.15 \ (drive.appfolder)16 / Allows read-only access to file metadata but17 5 | does not allow any access to read or download file content.18 \ (drive.metadata.readonly)19scope> 1輸入:1
代表使用:
1Full access all files, excluding Application Data Folder.意思是:
rclone 可以對你的 Google Drive 執行讀寫與管理檔案,這是最完整的權限。
service_account_file
畫面問:service_account_file>
直接按Enter。代表你不用 Service Account,也不需要 JSON 憑證,而是使用一般 OAuth 流程登入。
advanced config
畫面問:Edit advanced config? y/n>
你輸入:n
代表採用預設值,不進階調整。
是否使用 auto-config
畫面問:Use auto config? y/n>
你輸入:n
原因:你是在沒有 GUI 的遠端主機上操作,所以不能自動跳出瀏覽器登入。
手動給 token (你的瀏覽器機器產出的)
1Option config_token.2For this to work, you will need rclone available on a machine that has3a web browser available.4For more help and alternate methods see: https://rclone.org/remote_setup/5Execute the following on the machine with the web browser (same rclone6version recommended):7 rclone authorize "drive" "授權碼"8Then paste the result.9Enter a value.10config_token>1Option config_token.2For this to work, you will need rclone available on a machine that has3a web browser available.4For more help and alternate methods see: https://rclone.org/remote_setup/5Execute the following on the machine with the web browser (same rclone6version recommended):7 rclone authorize "drive" "授權碼"8Then paste the result.9Enter a value.10config_token>畫面問:config_token>
在任何有瀏覽器的電腦開 Terminal
輸入:
1rclone authorize "drive" "<授權碼>"1rclone authorize "drive" "<授權碼>"
這一步代表:你透過另一台有網頁瀏覽器的機器完成 Google OAuth 登入,再把結果回傳到伺服器。
Shared Drive 是否要設定
畫面問:Configure this as a Shared Drive? y/n>
你輸入:y
代表問 Google Drive 是否有 Team Drive。
你沒有 Team Drive,所以顯示:No Shared Drives found
完成設定並儲存
最後 rclone 問:Keep this “gdrive” remote?
你輸入:y
設定就正式完成。
測試 remote 是否正常
你輸入:
1rclone ls gdrive:1rclone ls gdrive:重點是要加冒號。執行後,你看到 Google Drive 裡全部的檔案列表。代表 gdrive remote 設定成功。

接著是 Shell Script 與 cron 排程設定
本備份系統用於在 Linux 伺服器上自動備份多個 WordPress 網站,包括:
-
資料庫備份
-
WordPress 主程式備份(排除 uploads)
-
Uploads 獨立備份
-
上傳至 Google Drive
-
本機不保留備份檔案
-
由單一設定檔管理多個網站
備份工具:
-
mysqldump
-
tar
-
rclone (Google Drive 備份上傳)
-
cron (排程)
備份資料夾結構
將建立以下結構:
1/root/backup/2 ├── config/3 │ └── sites.conf4 └── scripts/5 ├── backup-all.sh6 └── backup-uploads.sh1/root/backup/2 ├── config/3 │ └── sites.conf4 └── scripts/5 ├── backup-all.sh6 └── backup-uploads.sh建立系統目錄
1sudo mkdir -p /root/backup/config2sudo mkdir -p /root/backup/scripts1sudo mkdir -p /root/backup/config2sudo mkdir -p /root/backup/scripts設定檔 sites.conf
所有網站資訊集中管理於:
1/root/backup/config/sites.conf1/root/backup/config/sites.conf格式如下:
1# SITE_NAME | DB_NAME | DB_USER | DB_PASS | WP_PATH2<div></div>3stackpenguin|網頁對應的資料庫|資料庫使用者|密碼|網頁路徑1# SITE_NAME | DB_NAME | DB_USER | DB_PASS | WP_PATH2
3stackpenguin|網頁對應的資料庫|資料庫使用者|密碼|網頁路徑若有多個站點,每行新增一筆資料即可。
Script:備份資料庫與 WordPress 主程式
檔案位置:
1/root/backup/scripts/backup-all.sh1/root/backup/scripts/backup-all.sh內容如下:
1#!/bin/bash2<div></div>3CONFIG="/root/backup/config/sites.conf"4DATE=$(date +"%Y-%m-%d-%H%M")5REMOTE="gdrive"6REMOTE_BASE="wordpress-backups"7<div></div>8while IFS='|' read -r SITE DB_NAME DB_USER DB_PASS WP_PATH9do10 # 跳過空行與註解行11 [[ -z "$SITE" || "$SITE" =~ ^# ]] && continue12<div></div>13 echo "====================================="14 echo "開始備份:$SITE(DB + 主程式)"15 echo "====================================="16<div></div>17 TMP_DIR="/tmp/wp-backup-${SITE}-${DATE}"18 mkdir -p "$TMP_DIR"19<div></div>20 #######################################21 # 1. 備份資料庫(.sql)22 #######################################23 DB_FILE="$TMP_DIR/db-${SITE}-${DATE}.sql"24<div></div>25 echo "➤ 備份資料庫中…"26 mysqldump --single-transaction --quick --skip-lock-tables \27 -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" > "$DB_FILE"28<div></div>29 echo "➤ 上傳資料庫…(含進度)"30 rclone copy "$DB_FILE" "${REMOTE}:/${REMOTE_BASE}/${SITE}/db/" -P31<div></div>32 echo "➤ 清除舊版資料庫備份…(保留最新 2 份)"33 rclone ls "${REMOTE}:/${REMOTE_BASE}/${SITE}/db/" \34 | sort -k2 \35 | head -n -2 \36 | awk '{print $2}' \37 | while read OLD_FILE38 do39 echo "刪除:$OLD_FILE"40 rclone delete "${REMOTE}:/${REMOTE_BASE}/${SITE}/db/${OLD_FILE}"41 done42<div></div>43 #######################################44 # 2. 備份主程式(排除 uploads)45 #######################################46 WP_FILE="$TMP_DIR/wp-${SITE}-${DATE}.tar.gz"47<div></div>48 echo "➤ 壓縮 WordPress 主程式…(不含 uploads)"49 tar -czf "$WP_FILE" \50 --exclude="${WP_PATH}/wp-content/uploads" \51 "$WP_PATH"52<div></div>53 echo "➤ 上傳主程式…(含進度)"54 rclone copy "$WP_FILE" "${REMOTE}:/${REMOTE_BASE}/${SITE}/main/" -P55<div></div>56 echo "➤ 清除舊版主程式備份…(保留最新 2 份)"57 rclone ls "${REMOTE}:/${REMOTE_BASE}/${SITE}/main/" \58 | sort -k2 \59 | head -n -2 \60 | awk '{print $2}' \61 | while read OLD_FILE62 do63 echo "刪除:$OLD_FILE"64 rclone delete "${REMOTE}:/${REMOTE_BASE}/${SITE}/main/${OLD_FILE}"65 done66<div></div>67 #######################################68 # 3. 清除暫存69 #######################################70 rm -rf "$TMP_DIR"71<div></div>72 echo "=== ${SITE} 主程式與資料庫備份完成 ==="73 echo ""74<div></div>75done < "$CONFIG"76<div></div>77echo "全部網站的 DB + 主程式備份已完成"1#!/bin/bash2
3CONFIG="/root/backup/config/sites.conf"4DATE=$(date +"%Y-%m-%d-%H%M")5REMOTE="gdrive"6REMOTE_BASE="wordpress-backups"7
8while IFS='|' read -r SITE DB_NAME DB_USER DB_PASS WP_PATH9do10 # 跳過空行與註解行11 [[ -z "$SITE" || "$SITE" =~ ^# ]] && continue12
13 echo "====================================="14 echo "開始備份:$SITE(DB + 主程式)"15 echo "====================================="16
17 TMP_DIR="/tmp/wp-backup-${SITE}-${DATE}"18 mkdir -p "$TMP_DIR"19
20 #######################################21 # 1. 備份資料庫(.sql)22 #######################################23 DB_FILE="$TMP_DIR/db-${SITE}-${DATE}.sql"24
25 echo "➤ 備份資料庫中…"26 mysqldump --single-transaction --quick --skip-lock-tables \27 -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" > "$DB_FILE"28
29 echo "➤ 上傳資料庫…(含進度)"30 rclone copy "$DB_FILE" "${REMOTE}:/${REMOTE_BASE}/${SITE}/db/" -P31
32 echo "➤ 清除舊版資料庫備份…(保留最新 2 份)"33 rclone ls "${REMOTE}:/${REMOTE_BASE}/${SITE}/db/" \34 | sort -k2 \35 | head -n -2 \36 | awk '{print $2}' \37 | while read OLD_FILE38 do39 echo "刪除:$OLD_FILE"40 rclone delete "${REMOTE}:/${REMOTE_BASE}/${SITE}/db/${OLD_FILE}"41 done42
43 #######################################44 # 2. 備份主程式(排除 uploads)45 #######################################46 WP_FILE="$TMP_DIR/wp-${SITE}-${DATE}.tar.gz"47
48 echo "➤ 壓縮 WordPress 主程式…(不含 uploads)"49 tar -czf "$WP_FILE" \50 --exclude="${WP_PATH}/wp-content/uploads" \51 "$WP_PATH"52
53 echo "➤ 上傳主程式…(含進度)"54 rclone copy "$WP_FILE" "${REMOTE}:/${REMOTE_BASE}/${SITE}/main/" -P55
56 echo "➤ 清除舊版主程式備份…(保留最新 2 份)"57 rclone ls "${REMOTE}:/${REMOTE_BASE}/${SITE}/main/" \58 | sort -k2 \59 | head -n -2 \60 | awk '{print $2}' \61 | while read OLD_FILE62 do63 echo "刪除:$OLD_FILE"64 rclone delete "${REMOTE}:/${REMOTE_BASE}/${SITE}/main/${OLD_FILE}"65 done66
67 #######################################68 # 3. 清除暫存69 #######################################70 rm -rf "$TMP_DIR"71
72 echo "=== ${SITE} 主程式與資料庫備份完成 ==="73 echo ""74
75done < "$CONFIG"76
77echo "全部網站的 DB + 主程式備份已完成"Script:備份 uploads
檔案位置:
1/root/backup/scripts/backup-uploads.sh1/root/backup/scripts/backup-uploads.sh內容如下:
1#!/bin/bash2<div></div>3CONFIG="/root/backup/config/sites.conf"4DATE=$(date +"%Y-%m-%d-%H%M")5<div></div>6REMOTE="gdrive"7REMOTE_BASE="wordpress-backups"8<div></div>9while IFS='|' read -r SITE DB_NAME DB_USER DB_PASS WP_PATH10do11 # 跳過空行與註解12 [[ -z "$SITE" || "$SITE" =~ ^# ]] && continue13<div></div>14 UPLOAD_PATH="${WP_PATH}/wp-content/uploads"15<div></div>16 echo "==============================="17 echo "開始備份 uploads:${SITE}"18 echo "==============================="19<div></div>20 TMP_DIR="/tmp/wp-uploads-${SITE}-${DATE}"21 mkdir -p "$TMP_DIR"22<div></div>23 UPLOAD_FILE="${TMP_DIR}/uploads-${SITE}-${DATE}.tar.gz"24<div></div>25 # 壓縮 uploads26 tar -czf "$UPLOAD_FILE" "$UPLOAD_PATH"27<div></div>28 # 上傳至 Google Drive29 rclone copy "$TMP_DIR" "${REMOTE}:/${REMOTE_BASE}/${SITE}/uploads/"30<div></div>31 # 刪除暫存資料32 rm -rf "$TMP_DIR"33<div></div>34 echo "=== ${SITE} uploads 備份完成 ==="35 echo ""36done < "$CONFIG"37<div></div>38echo "所有網站 uploads 備份完成"1#!/bin/bash2
3CONFIG="/root/backup/config/sites.conf"4DATE=$(date +"%Y-%m-%d-%H%M")5
6REMOTE="gdrive"7REMOTE_BASE="wordpress-backups"8
9while IFS='|' read -r SITE DB_NAME DB_USER DB_PASS WP_PATH10do11 # 跳過空行與註解12 [[ -z "$SITE" || "$SITE" =~ ^# ]] && continue13
14 UPLOAD_PATH="${WP_PATH}/wp-content/uploads"15
16 echo "==============================="17 echo "開始備份 uploads:${SITE}"18 echo "==============================="19
20 TMP_DIR="/tmp/wp-uploads-${SITE}-${DATE}"21 mkdir -p "$TMP_DIR"22
23 UPLOAD_FILE="${TMP_DIR}/uploads-${SITE}-${DATE}.tar.gz"24
25 # 壓縮 uploads26 tar -czf "$UPLOAD_FILE" "$UPLOAD_PATH"27
28 # 上傳至 Google Drive29 rclone copy "$TMP_DIR" "${REMOTE}:/${REMOTE_BASE}/${SITE}/uploads/"30
31 # 刪除暫存資料32 rm -rf "$TMP_DIR"33
34 echo "=== ${SITE} uploads 備份完成 ==="35 echo ""36done < "$CONFIG"37
38echo "所有網站 uploads 備份完成"Script 權限設定
1sudo chmod +x /root/backup/scripts/backup-all.sh<br>sudo chmod +x /root/backup/scripts/backup-uploads.sh1sudo chmod +x /root/backup/scripts/backup-all.sh<br>sudo chmod +x /root/backup/scripts/backup-uploads.sh排程 cron 設定
設定 root cron:
1sudo crontab -e1sudo crontab -e加入:
1# 每日凌晨 3 點:DB + 主程式備份20 3 * * * /root/backup/scripts/backup-all.sh >/dev/null 2>&13<div></div>4# 每週一凌晨 4 點:uploads 備份50 4 * * 1 /root/backup/scripts/backup-uploads.sh >/dev/null 2>&11# 每日凌晨 3 點:DB + 主程式備份20 3 * * * /root/backup/scripts/backup-all.sh >/dev/null 2>&13
4# 每週一凌晨 4 點:uploads 備份50 4 * * 1 /root/backup/scripts/backup-uploads.sh >/dev/null 2>&1測試備份流程
測試 DB + 主程式
1sudo /root/backup/scripts/backup-all.sh1sudo /root/backup/scripts/backup-all.sh測試 uploads
1sudo /root/backup/scripts/backup-uploads.sh1sudo /root/backup/scripts/backup-uploads.sh備份位置
備份檔案將會出現在 Google Drive:




注意事項
-
rclone remote 名稱必須為 gdrive,若不同需修改 script。
-
需要確保 WordPress 資料庫使用者具備 PROCESS 權限:
GRANT PROCESS ON *.* TO 'zhuangwp'@'localhost'; FLUSH PRIVILEGES; -
若新增網站,只需在 sites.conf 新增一行即可。
-
本機不會保留任何備份檔案,全部在 /tmp 完成後會刪除。
我也試了備份的檔案能夠在本地恢復,可以閱讀這一篇。
部分資訊可能已經過時