跨平台備份是維運常見需求:將 Linux 伺服器的重要目錄打包壓縮,再透過 SMB/CIFS 協定傳送至 Windows 共享資料夾。本文提供一個可直接投入生產的 Bash 腳本,支援參數化指定備份來源、Windows 認證資訊與共享路徑,並內建錯誤檢查與日誌記錄,適合納入 crontab 定時執行。
tar.gz)/mnt/smbbox#!/bin/bash
# 用途:備份指定目錄並上傳至 Windows 共享
# 用法:backup.sh /home backup_user password //192.168.1.100/backup
FROM=$1 # 備份來源目錄
NTUSER=$2 # Windows 用戶名
NTPASSWD=$3 # Windows 密碼
NTSHARE=$4 # 共享路徑 //server/share
BACKDIR=$(hostname -s) # 以主機名為子目錄
MNT="/mnt/smbbox" # 本地掛載點
NOW=$(date +"%m-%d-%Y-%I_%M%P")
BAKFILE="backup.$NOW.tar.gz"
# 參數檢查
if [ "$#" -ne 4 ]; then
echo "Syntax: $(basename $0) {Linux-dir} {NT-user} {NT-pass} {//NT-server/share}"
exit 1
fi
# 來源目錄是否存在
if [ ! -d "$FROM" ]; then
echo "Backup source directory $FROM does NOT exist"
exit 2
fi
# 1. 打包壓縮到 /tmp
tar -czf "/tmp/$BAKFILE" "$FROM"
# 2. 掛載 Windows 共享
[ ! -d "$MNT" ] && mkdir -p "$MNT"
mount -t cifs -o username="$NTUSER",password="$NTPASSWD",vers=1.0 "$NTSHARE" "$MNT"
# 3. 確保遠端子目錄存在
[ ! -d "$MNT/$BACKDIR" ] && mkdir -p "$MNT/$BACKDIR"
# 4. 複製備份檔
cp "/tmp/$BAKFILE" "$MNT/$BACKDIR/"
# 5. 強制同步並卸載
sync
umount "$MNT"
echo "Backup completed: $BAKFILE -> $NTSHARE/$BACKDIR/"
舊版使用 smbfs,現代核心建議改用 cifs,並加上 vers=1.0 相容舊版 Windows(如 Server 2000/2003)。若對方支援 SMB 2.0+,可移除 vers 參數以獲得更好效能與安全性。
腳本以明文參數傳遞密碼,僅適合內網受信環境。生產環境建議:
credentials=/path/to/.smbcred 檔案(權限 600)# 每天凌晨 2:30 執行備份
30 2 * * * /opt/scripts/backup.sh /home backup_user 'P@ssw0rd' //192.168.1.100/backup >> /var/log/backup.log 2>&1
| 現象 | 可能原因 | 解決方式 |
|---|---|---|
| mount error(13): Permission denied | 用戶名/密碼錯誤、或共享權限不足 | 確認 Windows 共享「讀/寫」權限、嘗試加上 domain=WORKGROUP |
| No space left on device | /tmp 或遠端磁碟空間不足 | 清理舊備份、調整保留策略 |
| tar: Removing leading '/' | 使用絕對路徑打包 | 加上 -P 參數保留絕對路徑,或改用相對路徑 |
find $MNT/$BACKDIR -mtime +30 -delete 自動清理 30 天前備份rsync 增量同步,減少頻寬佔用