粉好用ㄟ自動備份資料庫、網站到信箱、FTP 的腳本 🔥💾
從「手動備份累到半死」進化成「每天自動幫你搬金庫」的懶人神器
為什麼你一定要自動備份?先講一個真實痛點故事 😱
想像一下:你辛辛苦苦經營的 WordPress 網站,就像你在家裡養的一隻貓。每天餵食(更新文章)、梳毛(修圖)、陪玩(回留言),結果有一天電腦突然藍屏、主機板燒掉,或是被駭客攻擊,整間房子(網站)直接消失。
這時候你才驚覺:原來自己從來沒有真正的「備份」過! 手動下載資料庫、壓縮整個資料夾、再上傳到雲端……光是想到就懶得動,結果常常拖到「出事才後悔」。
這篇就是為了拯救這種「知道要備份、卻總是拖延」的人而寫的。我直接把自己用了很多年、改了又改的自動化腳本公開給大家。參考了貓言貓語大大的原始文章,再根據一般人比較容易理解的方式調整過。不管你是用 cPanel 共享主機、還是自己租 VPS,都可以直接套用。
🔥 懶人包結論:這支腳本會自動把「網站檔案」跟「資料庫」壓縮成兩個 tar.gz,然後上傳到你指定的 FTP 空間,還會自動刪除三天前的舊檔,讓你永遠不用擔心空間爆掉。
更新歷史(從 2010 年到現在,還在持續進化)📅
這支腳本不是一天就寫出來的,而是跟著時代一直改版。以下是真實更新紀錄:
- ✔️ 2010/10/01 – 首次發表
- ✔️ 2010/10/09 – 因為有人搞不懂怎麼用在 cPanel 上面,而且要簡單易懂……還好看到貓有寫新的文章,不然真想揍人。總之,08 回來沒吃到西堤你丟災 😒👊💪
- ✔️ 2010/10/25 – 添加自動修復資料庫語法
- ✔️ 2014/08/27 – 修改信件寄出語法
- ✔️ 2019/10/02 – 添加自動修復 MariaDB 資料庫語法
- ✔️ 2019/11/01 – 新增 Dropbox Uploader 的自動備份腳本
- ✔️ 2025/05/26 – 新增 備份 LINE 電腦版對話紀錄的批次檔腳本
從 2010 年到現在已經超過十五年,還能繼續用,代表這套邏輯真的很穩。
事前準備:就像搬家前先準備紙箱一樣 📦
在開始跑腳本之前,你必須先做兩件事,缺一不可:
- ❶ 登入 FTP,在
目錄底下建立一個叫1public_html的資料夾。這就像你搬家前,先在新家空出一個房間專門放紙箱。1backup
- ❷ 把下面的腳本內容存成
,放到剛剛建立的1WebDBtoFTP.sh資料夾裡面。1backup
建立資料夾的指令很簡單:
|
1 |
mkd /public_html/backup |
接著把腳本上傳進去後,記得立刻給它「執行權限」,不然系統會當成普通文字檔,根本不鳥它:
|
1 |
chmod 700 /public_html/backup/WebDBtoFTP.sh |
🚨 畫重點!千萬別踩雷:權限一定要設成 700。設太高(像 777)會有資安風險,設太低又跑不起來。
完整腳本內容(直接複製貼上就對了)📝
以下就是完整的
|
1 |
WebDBtoFTP.sh |
。紅色字的地方是你一定要自己改的參數,其他地方盡量不要動。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
#!/bin/bash ############### 你要修改的地方從這裡開始 ############### MYSQL_USER="MySQL使用者名稱" # MySQL使用者名稱 MYSQL_PASS="MySQL密碼" # MySQL密碼 HOSTNAME="要備份的網站名稱" # 要備份的網站名稱 WEB_DATA="要備份的網站位置" # 要備份的網站位置 BACKUP_DIR="要備份的網站位置" # 本機存放備份檔的位置 FTP_IP="FTP地址" # FTP地址 FTP_USER="FTP使用者名稱" # FTP使用者名稱 FTP_PASS="FTP密碼" # FTP密碼 FTP_BACKUP="FTP上存放備份檔案的位置" # FTP上存放備份檔案的位置 ############### 你要修改的地方從這裡結束 ############### MYSQL_PATH=mysql # MySQL程式路徑,可用whereis mysql指令查詢 MYSQLDUMP=mysqldump # MySQLDUMP程式路徑,可用whereis mysqldump指令查詢 MYSQLCHECK=mysqlcheck # MySQLCHECK程式路徑,可用whereis mysqlcheck指令查詢 # 定義資料庫的名字和舊資料庫的名字 DBName=$HOSTNAME-MySQL_$(date +"%Y%m%d").tar.gz OldDB=$HOSTNAME-MySQL_$(date -d -3day +"%Y%m%d").tar.gz # 定義網站資料的名字和舊網站資料的名字 WebName=$HOSTNAME-Web_$(date +%Y%m%d).tar.gz OldWeb=$HOSTNAME-Web_$(date -d -3day +"%Y%m%d").tar.gz ################################################## ### 刪除本地端3天前的資料 echo "==================================================" echo "Backup databases and web started" find "$BACKUP_DIR" -mtime +3 -type d -exec rm -rf {} \; rm -f $BACKUP_DIR/$HOSTNAME-MySQL_$(date -d -3day +"%Y%m%d").tar.gz rm -f $BACKUP_DIR/$HOSTNAME-Web_$(date -d -3day +"%Y%m%d").tar.gz ### 建立備份資料夾 echo "==================================================" echo "To create a new directory, set filename based on the date" mkdir -p $BACKUP_DIR cd $BACKUP_DIR # 最佳化並自動修復資料庫 echo "==================================================" echo "Check the databases with optimize tables, auto repair" $MYSQLCHECK -u $MYSQL_USER -p$MYSQL_PASS -oA --auto-repair > /dev/null 2>&1 # 輸出資料庫,如果使用ROOT帳號會輸出成一個資料庫一個SQL檔 echo "==================================================" echo "To dump each database in a separate file" for db in `$MYSQL_PATH -u $MYSQL_USER -p$MYSQL_PASS -B -N -e 'SHOW DATABASES' | xargs`; do ($MYSQLDUMP -u $MYSQL_USER -p$MYSQL_PASS --default-character-set=utf8mb4 --single-transaction --skip-lock-tables ${db} > ${db}.sql) done # 壓縮所有資料庫為一個壓縮檔並刪除所有的SQL檔 echo "==================================================" echo "Compressing datebase files" rm -f information_schema.sql mysql.sql performance_schema.sql tar zcfP $BACKUP_DIR/$DBName $BACKUP_DIR/*.sql rm -f $BACKUP_DIR/*.sql #壓縮網站資料 echo "Compressing website files" tar zcfP $BACKUP_DIR/$WebName $WEB_DATA --exclude=wp-content/cache --exclude=wp-content/akeebabackupwp --exclude=wp-content/updraft # 上傳到FTP空間並刪除FTP空間過期的資料 echo "==================================================" echo "Send files via FTP" ftp -v -n $FTP_IP << END user $FTP_USER $FTP_PASS type binary lcd $BACKUP_DIR cd $FTP_BACKUP delete $OldDB delete $OldWeb put $DBName put $WebName bye END echo "==================================================" echo "Web and Database backup successfully completed!" echo "==================================================" # ring a bell printf '\007' |
腳本到底在幹嘛?用「搬家」比喻一次講清楚 🏠
很多人看到一長串指令就頭昏,我們用「搬家」來比喻,一次就懂:
| 步驟 | 腳本在做的事 | 日常生活比喻 |
|---|---|---|
| 1 | 刪除 3 天前的舊備份 | 把過期的舊紙箱丟掉,避免房間爆滿 |
| 2 | 建立當天日期的新資料夾 | 準備今天專用的新紙箱 |
| 3 | 自動修復 + 最佳化資料庫 | 搬家前先把家具擦乾淨、修好壞掉的輪子 |
| 4 | 把每個資料庫各自匯出成 .sql | 把書櫃、衣櫃、廚房用具分別裝箱並貼標籤 |
| 5 | 壓縮成一個大 tar.gz | 把所有小箱子再裝進一個大紙箱,方便搬運 |
| 6 | 壓縮整個網站資料夾(排除快取) | 把整間房子的東西打包,但跳過垃圾桶跟臨時雜物 |
| 7 | 上傳到 FTP 並刪除遠端舊檔 | 把大紙箱送到遠端倉庫,同時把倉庫裡超過三天的舊箱丟掉 |
這樣是不是清楚多了?整個過程就像請了一位很靠譜的搬家師傅,每天固定時間自動來幫你打包、運送、清理舊東西。
參數怎麼填?最容易搞錯的地方一次講透 ✍️
腳本最上面那一段「你要修改的地方」,是整個成敗的關鍵。我用表格直接對照給你看:
| 參數名稱 | 你要填什麼 | 範例 |
|---|---|---|
| MYSQL_USER | MySQL 使用者名稱 | mywpuser |
| MYSQL_PASS | MySQL 密碼 | P@ssw0rd123 |
| HOSTNAME | 網站暱稱(會出現在檔名) | mysite |
| WEB_DATA | 網站實際路徑 | /home/使用者/public_html |
| BACKUP_DIR | 本機暫存備份的位置 | /home/使用者/public_html/backup |
| FTP_IP | FTP 主機位址 | ftp.example.com |
| FTP_USER / FTP_PASS | FTP 帳號密碼 | 你自己的 FTP 帳密 |
| FTP_BACKUP | FTP 上要存放備份的路徑 | /backup |
填完之後記得存檔,然後用 FTP 軟體把權限設成 700。
怎麼讓它每天自動跑?cPanel + crontab 兩種方式 ⏰
腳本寫好只是第一步,重點是讓它「每天自己跑」。
方法一:cPanel 的 Cron Jobs(最簡單,適合小白)
到 cPanel 控制台 → Cron Jobs,新增一筆:
|
1 |
/home/<span style="color: #ff6b6b; background-color: #171717; padding: 2px 6px; border-radius: 4px; font-weight: bold;">使用者名稱</span>/public_html/backup/WebDBtoFTP.sh |
時間建議設在凌晨 1 點 15 分,那時候網站流量最低,比較不會影響速度。
方法二:直接用 crontab(VPS 或有 root 權限的人)
|
1 2 |
sudo crontab -e 15 1 * * * sh /public_html/backup/WebDBtoFTP.sh |
這樣每天凌晨 1:15 就會自動執行一次,完全不用你插手。
💡 你知道嗎?很多人都是「設了排程就忘記」,結果三年後網站掛掉才發現備份其實一直有在跑。這就是自動化的威力。
另一個超實用版本:只備份資料庫寄到信箱 📧
有時候你只想備份資料庫,不想動整個網站檔案,或是你的 FTP 空間不夠大。這時候可以用下面這支「寄到信箱」版本:
檔名建議叫
|
1 |
DBtoMail.sh |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#!/bin/bash ############### 你要修改的地方從這裡開始 ############### MYSQL_PATH=mysql # MySQL程式路徑,cPanel或安裝時沒指定位置的不用修改 MYSQLDUMP=mysqldump # MySQLDUMP程式路徑,cPanel或安裝時沒指定位置的不用修改 MYSQLCHECK=mysqlcheck # MySQLCHECK程式路徑,cPanel或安裝時沒指定位置的不用修改 MYSQL_USER=root # MySQL使用者名稱 MYSQL_PASS=MySQL密碼 # MySQL密碼 MAIL_TO=qoo@gmail.com # 資料庫發送到的郵箱 HOSTNAME=qoo.com # 主機名稱 BACKUP_DIR=/public_html/backup # 備份檔位置 ############### 你要修改的地方從這裡結束 ############### # 定義資料庫的名字和舊資料庫的名字 DBName=$HOSTNAME-DB_$(date +"%Y%m%d").tar.gz # 刪除本地7天前的資料 cd $BACKUP_DIR rm -f $BACKUP_DIR/$HOSTNAME-DB_$(date -d -7day +"%Y%m%d").tar.gz # 最佳化並自動修復資料庫 $MYSQLCHECK -u $MYSQL_USER -p$MYSQL_PASS -oA --auto-repair > /dev/null 2>&1 # 輸出資料庫,如果使用ROOT帳號會輸出成一個資料庫一個SQL檔 for db in `$MYSQL_PATH -u $MYSQL_USER -p$MYSQL_PASS -B -N -e 'SHOW DATABASES' | xargs`; do ($MYSQLDUMP -u $MYSQL_USER -p$MYSQL_PASS --default-character-set=utf8mb4 --single-transaction --skip-lock-tables ${db} > ${db}.sql) done # 壓縮所有資料庫為一個壓縮檔 rm -f information_schema.sql mysql.sql performance_schema.sql tar zcfP $BACKUP_DIR/$DBName $BACKUP_DIR/*.sql rm -f $BACKUP_DIR/*.sql # 附件方式寄送資料庫壓縮檔到信箱,如壓縮檔超過25MB請勿使用gmail信箱,Yahoo很會掉信也別用 echo "DBBACKUP" | mutt -s "$DBName" -a $BACKUP_DIR/$DBName $MAIL_TO |
這支腳本會:
- ✔️ 自動修復並最佳化資料庫
- ✔️ 把每個資料庫各自匯出
- ✔️ 壓縮成一個 tar.gz
- ✔️ 直接當附件寄到你指定的信箱
- ✔️ 自動刪除 7 天前的舊檔
🚨 畫重點!千萬別踩雷:如果壓縮檔超過 25MB,千萬不要用 Gmail,因為會被擋。Yahoo 也很會掉信,建議用自己的企業信箱或是其他比較穩的服務。
為什麼我要把「一個大 SQL」改成「每個資料庫各自一個檔」?🤔
原始貓言貓語的寫法是把所有資料庫導成一個超大的 sql 檔,像這樣:
|
1 |
/usr/local/mysql/bin/mysqldump -uroot -p123456 --databases db1 db2 db3 > /home/backup/databackup.sql |
這樣做的確簡單,但對我這種比較龜毛的人來說很不方便。因為萬一哪天只想還原其中一個資料庫,你還得把整個大檔打開來找,超痛苦。
所以我改成:先各自匯出成獨立的 .sql,再統一壓縮成一個 tar.gz。這樣你日後要還原的時候,可以直接解壓縮後挑你需要的那個資料庫,乾淨俐落。
這就像搬家時,你選擇「每個房間各自裝箱並貼標籤」,而不是把所有東西丟進一個超大黑色垃圾袋。雖然多花一點時間,但之後要找東西時會感謝自己。
常見問題一次解答(看完幾乎不會再卡住)❓
- ❶ 腳本跑完沒有檔案?
先檢查權限有沒有設成 700,再檢查 MySQL 帳密有沒有填錯。可以用來除錯,會把每一步都印出來。1sh -x WebDBtoFTP.sh - ❷ FTP 上傳失敗?
確認 FTP 帳密、路徑是否正確,以及主機有沒有允許腳本使用 ftp 指令。有些共享主機會把 ftp 指令關掉。 - ❸ 資料庫太大,壓縮很久?
這很正常。可以考慮排除一些不重要的資料庫,或是改用只備份資料庫寄信箱的版本。 - ❹ 想改成保留 7 天而不是 3 天?
把腳本裡所有的改成1-3day就好,連刪除遠端舊檔的地方也要一起改。1-7day - ❺ MariaDB 跟 MySQL 有差嗎?
現在大部分主機都是 MariaDB,但指令幾乎完全相容,腳本已經有針對 MariaDB 做過調整,可以直接用。
寫在最後:備份不是「以防萬一」,而是「一定會發生」🛡️
很多人把備份當成「有空再做」的事情,結果總是在出事之後才後悔。其實自動備份就像買保險:你希望永遠用不到,但真的出事時,它會救你一命。
這支腳本我用了超過十五年,從最早的共享主機一路用到現在的 VPS,中間經歷過好幾次主機商倒閉、硬碟損壞、誤刪資料夾……每一次都是靠它把網站救回來。
現在我把完整版本公開,希望也能幫到需要的人。如果你有改得更好的版本,或是遇到什麼奇怪的錯誤,歡迎留言告訴我,我們一起讓這支腳本變得更強。
記得:備份做一次,安心睡十年。
感謝貓言貓語大大的原始文章啟發 🙏
也感謝所有曾經回報問題、幫忙測試的網友們。
逆向行駛 最愛的最殘酷、最美的最虛無
感謝!終於是把不能自己備份的mediawiki弄成每天備份了。這樣就不怕服務器傲嬌了。 ?