提醒:本页面将不再更新、维护或者支持,文章、评论所叙述内容存在时效性,涉及技术细节或者软件使用方面不保证能够完全有效可操作,请谨慎参考!

最近Linux搞得比较多,之前有个精简版的VPS服务器,今天又拿过来测试,主要是定期为上面的网站做个备份,大概看了一下,需要备份的分别有两个地方:1. 网站的主目录;2. MySQL数据库。于是想搞个定时发送备份文件到指定邮箱的做法。Linux刚上手,也不是很熟练,参考了一些命令,以及前辈们的备份做法,硬着头皮写了Bash Shell脚本,初步测试下来基本满足了要求,在这里分享给大家参考,不过 建议大家使用前在实验环境下测试确保正常 ,如果因为潜在问题造成损失我可不负责哦:-)当然对于我这种新手而言,这样的脚本难免会有Bug,希望高手不吝指出:

#!/bin/bash

# Author: wangye
# For more information please visit:
# http://wangye.org/
# 请在使用本脚本前做好测试工作,脚本功能仅供参考,
# 对于可能的潜在问题造成损失,本人不承担责任。

MYSQL_USERNAME="mysql-username"
MYSQL_PASSWORD="mysql-password"

# 下面这行指示接收备份文件的电子邮件地址
BACKUP_RECEVIER="[email protected]"
BACKUP_FILENAME="/var/sample-site" # 需要备份的目录
BACKUP_DBNAME="sample" # 需要备份的数据库名称
BACKUP_PREFIX="backup_" # 备份文件的前缀

# 下面一些命令路径可以通过whereis获取
MYSQLDUMP_PATH="/usr/bin" # mysqldump 命令所在的路径
TARCOMPRESSOR_PATH="/bin" # tar 命令所在的路径
RM_PATH="/bin" # rm 命令所在的路径
MUTTMAIL_PATH="/usr/bin" # mutt 命令所在的路径
TEMP_PATH="/tmp" # 临时目录

# 产生临时名称形如 backup_20120221 名称
make_backup_name() {
    TEMPNAME=${BACKUP_PREFIX}$(date +"%Y%m%d")
}

# 产生临时备份目录
make_backup_dir() {
    make_backup_name
    TEMPDIR=${TEMP_PATH}/$?
    mkdir -m 777 -p $TEMPDIR
}

backup_files() {
    ${TARCOMPRESSOR_PATH}/tar -zcvf \
        ${TEMP_PATH}/${TEMPNAME}.tar.gz ${BACKUP_FILENAME}
}

backup_databases() {
    local EXPORTDIR=$1
    ${MYSQLDUMP_PATH}/mysqldump -u${MYSQL_USERNAME} \
      -p${MYSQL_PASSWORD} \
      ${BACKUP_DBNAME} >${EXPORTDIR}/${BACKUP_DBNAME}.sql

    ${TARCOMPRESSOR_PATH}/tar -zcvf \
      ${TEMP_PATH}/${TEMPNAME}_${BACKUP_DBNAME}.tar.gz ${EXPORTDIR}
}

send_byemail() {
    echo "**IMPORTANT BACKUP** Hi! :-)\n\n$(uname -a)"| \
        $MUTTMAIL_PATH/mutt -s "** System Backup$(date +%Y-%m-%d)" \
            -a ${TEMP_PATH}/${TEMPNAME}_${BACKUP_DBNAME}.tar.gz \
             ${TEMP_PATH}/${TEMPNAME}.tar.gz -- \
            ${BACKUP_RECEVIER}
}

# 清除产生的临时文件(使用了rm -rf怕怕中,不过目标路径正确就OK啦)
cleanup() {
    $RM_PATH/rm -rf $TEMPDIR
    $RM_PATH/rm -rf ${TEMP_PATH}/${TEMPNAME}_${BACKUP_DBNAME}.tar.gz
    $RM_PATH/rm -rf ${TEMP_PATH}/${TEMPNAME}.tar.gz
}

main() {
   make_backup_dir
   backup_databases $TEMPDIR
   backup_files
   send_byemail
   cleanup
}

main

exit 0

其实也没什么技术含量,最担心的是 cleanup() 函数下的危险的 rm -rf ,不过路径是正确的也没什么问题了。最无聊的地方是指定命令路径,写到最后,感觉这里有点多此一举,基本上命令都是配置好的,不需要指定路径直接输入命令名称就可以运行的,可能觉得RedHat系和Debian系在目录路径上有点区别,这里为兼容就这样写了,大家在移植到自己的系统上时记得修改这边,通过 whereis 命令找出相应的路径,比如 whereis mysqldump ,找到mysqldump的路径。

这里处理的流程是这样的,先是在/tmp临时目录下建立一个临时目录以形如 backup_20120221 名称,在这个目录下存放mysqldump导出的SQL文件,然后通过tar命令压缩这个目录,接着通过tar命令压缩指定要备份的文件夹,这两个压缩的文件均存放于临时目录/tmp下。然后通过mutt将这两个备份文件发送到指定的邮箱,最后执行cleanup函数,通过rm -rf清除掉/tmp临时目录下产生的文件。

可能有童鞋要问,为什么要专门为mysqldump出来的一份sql文件创建一个临时目录?呵呵,其实我当初想搞个备份多个数据库和文件夹的,后来放弃了这个想法,就搞了个简单的先用,如果是多个数据库备份会产生多个sql文件,一起丢进这个创建的文件夹,然后打包,多省事。

这里还有一个注意点就是mutt命令,我在网上搜索如果通过mutt命令添加并发送多个附件的邮件,结果有个童鞋博客上写到要添加的每个附件前面加上-a,就是-a xxx1.zip -a xxx2.zip,非常不幸,这样的做法是 行不通 的。参考了mutt的帮助后得知,多个附件应该形如这样添加-a xxx1.zip xxx2.zip --多个文件以空格隔开,然后最后一个文件结尾要有两个短横线--(注意是两个短横线,这里可能被博客转换成一个长横线了,可以参考上面代码的send_byemail函数部分)。

好了,脚本编写完毕,假如我们放在/root目录下并且命名为backup.sh,下面给脚本加上可执行属性:

chmod 777 /root/backup.sh

然后通过 /root/backup 或者 sh /root/backup.sh 测试执行我们的备份脚本,如果一切正常的话,接着进行下面的步骤,将脚本加入crontab定时任务计划:

crontab -e
50 1 * * * /root/backup.sh

基本上就这些了,祝大家成功!哦,对了,我的测试环境是Debian 5。

补充

mutt发送电子邮件的命令一般系统不自带,需要额外安装,可以考虑下面的安装指令:

# Debian 或者 Ubuntu系统使用下面这条
apt-get -y install mutt
# RedHat 或者 CentOS系统使用下面这条
yum -y install mutt