rsync 是 Linux 增量備份、鏡像同步、跨機部署的瑞士刀。本文系統解析核心參數、SSH 金鑰免密配置、排除模式、帶寬限制、刪除策略與生產級自動化腳本。
rsync [選項] 來源 目的
# 本地→本地
rsync -av /src/ /dst/
# 本地→遠端
rsync -av /src/ user@host:/dst/
# 遠端→本地
rsync -av user@host:/src/ /dst/
# 遠端→遠端(需兩端互信)
rsync -av user@host1:/src/ user@host2:/dst/
alias rsync-prod='rsync -avz --progress --delete --exclude="*.tmp" --exclude=".git"'
# -a 歸檔模式 = -rlptgoD(遞歸、連結、權限、時間、擁有者、群組、設備)
# -v 顯示進度
# -z 壓縮傳輸
# --progress 即時顯示速度、剩餘時間
# --delete 目的端刪除來源不存在的檔案(鏡像同步)
# --exclude 排除模式(可多次使用)
# 1. 產生金鑰(Ed25519 更短更快)
ssh-keygen -t ed25519 -C "rsync-backup-$(hostname)"
# 2. 推送公鑰至備份端
ssh-copy-id -i ~/.ssh/id_ed25519.pub backup@backup-server
# 3. 測試
ssh backup@backup-server "echo OK"
# 4. 限制金鑰僅能執行 rsync(安全加強)
# 在備份端 ~/.ssh/authorized_keys 公鑰行首加入:
command="rsync --server --sender -vlOgDtpre.iLsfxC . /backup/path/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc ssh-ed25519 AAAA... comment
| 需求 | 參數 | 說明 |
|---|---|---|
| 排除所有 .log | --exclude="*.log" | 萬用字元匹配檔名 |
| 排除特定目錄 | --exclude="/var/cache/" | 絕對路徑(相對來源根) |
| 排除多個模式 | --exclude={"*.tmp","*.pid","node_modules"} | Bash 擴展(需 bash 環境) |
| 從檔案讀取排除清單 | --exclude-from=/etc/rsync.exclude | 每行一個模式,適合版控管理 |
| 只同步特定副檔名 | --include="*.conf" --exclude="*" | 先 include 再 exclude |
# 限制 10MB/s(生產網路不佔滿)
rsync -avz --bwlimit=10240 /src/ user@host:/dst/
# 斷點續傳(大檔案網路不穩)
rsync -avz --partial --append-verify /src/big.iso user@host:/dst/
# --partial 保留未完成檔案
# --append-verify 斷點處校驗後續傳
| 參數 | 行為 | 風險 |
|---|---|---|
--delete | 傳輸前刪除目的端多餘檔案 | 來源誤刪會同步刪除目的端 |
--delete-before | 傳輸前刪除(同 --delete) | 同上 |
--delete-during | 傳輸過程中逐個刪除 | 較安全,但較慢 |
--delete-after | 傳輸完成後刪除 | 最安全,需雙倍暫存空間 |
--delete-excluded | 同時刪除被排除的檔案 | 極危險,慎用 |
建議:備份用 --delete-after;鏡像部署用 --delete-during。
#!/bin/bash
# /usr/local/bin/rsync_backup.sh
set -euo pipefail
SRC="/data/www/"
DST="backup@backup-srv:/backup/www/$(hostname)/"
LOG="/var/log/rsync_backup.log"
LOCK="/var/run/rsync_backup.lock"
EXCL="/etc/rsync_backup.exclude"
# 單例鎖
exec 9>"$LOCK"
flock -n 9 || { echo "$(date) Another instance running" >>"$LOG"; exit 1; }
echo "=== $(date) START ===" >>"$LOG"
rsync -avz --delete-after \
--bwlimit=20480 \
--exclude-from="$EXCL" \
--log-file="$LOG" \
"$SRC" "$DST" 2>&1 | tail -20 >>"$LOG"
RET=$?
echo "=== $(date) END (exit=$RET) ===" >>"$LOG"
# 保留近 30 天日誌
find /var/log -name "rsync_backup.log.*" -mtime +30 -delete
exit $RET
*.tmp
*.pid
*.swp
.cache/
node_modules/
vendor/
storage/logs/*.log
storage/framework/cache/
.phpunit.result.cache
# 每天 02:30 執行
30 2 * * * root /usr/local/bin/rsync_backup.sh >>/var/log/rsync_backup_cron.log 2>&1
rsync -avzn --delete /src/ user@host:/dst/ (-n dry-run) 先看會刪什麼grep "deleting" /var/log/rsync_backup.log 審計實際刪除du -sh /backup/www/$(hostname) 對比來源大小結語: rsync 核心在「增量、壓縮、可控刪除」。鎖定 -avz --delete-after --bwlimit --exclude-from 這組黃金參數,配合 SSH 金鑰限制命令、單例鎖、dry-run 審計,即可構建「可信、可控、可審計」的企業級備份/同步體系。