说实话,宝塔面板的默认备份功能,对大多数用户来说确实够用。但真到了需要精细化操作的时候,你就会发现它有点“不够用”——比如,我就只想备份某个站点的附件目录,而不是整个网站。这时候,面板自带的“网站备份”功能就帮不上忙了,它只支持整站或数据库,没法单独选一个子目录出来。
那怎么搞呢?答案藏在命令行里——用计划任务配合 Shell 命令,直接写备份脚本。听起来有点绕,但实际走一遍,其实很清晰。
备份命令:用 tar 打包指定目录,别用面板自带的“网站备份”
想备份特定目录,像 /www/wwwroot/example.com/uploads 这种,必须绕过图形界面,直接写 shell 命令到计划任务里。关键点有三个:路径必须绝对、权限必须对、压缩包名要带时间戳防止覆盖。
具体命令长这样:
tar -zcf /www/backup/uploads_$(date +\%Y\%m\%d_\%H\%M).tar.gz -C /www/wwwroot/example.com uploads
这里有几个细节值得注意:
-C参数指定了根目录,后面跟相对路径uploads,这样解压出来的文件不会带一长串冗余的目录层级,干净利落。- 目标备份路径(比如
/www/backup)必须提前建好,并且宝塔的运行用户(通常是www)要有写权限。可以跑一下mkdir -p /www/backup && chown www:www /www/backup来搞定。 - 千万别用
~或./这种相对路径——计划任务里的当前工作目录不固定,踩坑的概率很高,写绝对路径才是王道。
在宝塔“计划任务”里添加 Shell 脚本,不是直接粘贴命令
很多人习惯直接在计划任务的“Shell 脚本”输入框里贴一大段命令,但这样容易出问题——引号转义、换行截断,调试起来很头疼。更稳妥的做法,是把命令写进一个脚本文件,然后让计划任务去调用它。
操作步骤:
- 新建脚本:
vi /www/backup/backup_uploads.sh,把上面的tar命令写进去,记得加上#!/bin/bash。 - 赋予执行权限:
chmod +x /www/backup/backup_uploads.sh。 - 回到宝塔计划任务,类型选“Shell 脚本”,脚本内容填:
/www/backup/backup_uploads.sh。 - 执行周期按需设置,比如每天凌晨 2 点:
0 2 * * *。注意,宝塔用的是系统 crond,时区以服务器为准。
这样写,后面想改命令、加逻辑,都直接在脚本里改,比在面板输入框里折腾省心多了。
备份后自动清理 7 天前的旧文件,防止磁盘撑爆
不加清理逻辑,备份文件会越堆越多,迟早把磁盘撑满。宝塔计划任务本身没有“保留 N 份”的选项,所以得手动加一条 find 删除命令。
在脚本末尾补上这行:
find /www/backup -name "uploads_*.tar.gz" -mtime +7 -delete
说明:
-mtime +7表示修改时间超过 7 天的文件。注意,tar打包后文件修改时间就是打包时间,所以这个条件正好是“保留最近 7 天的备份”。- 稳妥起见,先测试再删:把命令改成
find ... -print,看看会列出哪些文件,确认无误再换成-delete。 - 如果备份文件名里可能包含空格或特殊字符,
find可能会误判。这时可以用-name "uploads_[0-9]*.tar.gz"来限定,更安全。
验证备份是否成功,不能只看计划任务“执行成功”状态
宝塔计划任务显示“执行成功”,只代表 Shell 进程退出码是 0,不代表 tar 真的打完了、没报错、文件能解压。这一步如果漏掉,可能备份了几个月,结果发现全是空包,那才叫崩溃。
所以,必须加校验:
- 在脚本末尾加一段日志记录:
if [ $? -eq 0 ]; then echo "$(date) backup OK" >> /www/backup/backup.log; else echo "$(date) backup FAIL" >> /www/backup/backup.log; fi。 - 定期手动抽样解压测试:
tar -tzf /www/backup/uploads_20240501_0200.tar.gz | head -n 5,看看是否列出了预期的文件。 - 另外,检查文件大小也是个好习惯:
ls -lh /www/backup/uploads_*.tar.gz。如果连续几天的备份文件都只有几 KB,那大概率是tar执行失败了,但被忽略了。
这里最容易被忽略的一点是:tar 可能因为权限不足跳过了某些子目录,但依然返回退出码 0。所以,日志记录和抽样检查,两者缺一不可。
