做网站最重要的是什么?数据!数据,是网站之本,备份,是每一个站长都应该重视的事情。但同时,备份也是一件繁琐和重复的事情。所以,这些事情,肯定能做到自动化的。
下面来介绍一下这个一键备份脚本 backup.sh。

总结一下 backup.sh 特点:

1、支持 MySQL/MariaDB/Percona 的数据库全量备份或选择备份;
2、支持指定目录或文件的备份;
3、支持加密备份文件(需安装 openssl 命令,可选);
4、支持上传至 Google Drive(需先安装 gdrive 并配置,可选);
5、支持在删除指定天数本地旧的备份文件的同时,也删除 Google Drive 上的同名文件(可选)。

 

2016 年 8 月 21 日更新:
1、新增:指定 MySQL/MariaDB 的数据库名进行备份,可以同时指定多个;
2、新增:删除指定天数本地旧的备份文件。
2016 年 9 月 8 日更新:
1、新增:删除指定天数本地旧的备份文件的同时,可选删除 Google Drive 上的同名文件。
2016 年 11 月 29 日更新:
1、新增:上传备份文件到 FTP 选项;
2、新增:删除指定天数本地旧的备份文件的同时,可选删除 Google Drive 及 FTP 上的同名文件。

教程模式开启:

1、下载该脚本并赋予执行权限

wget --no-check-certificate https://github.com/teddysun/across/raw/master/backup.sh
chmod +x backup.sh

2、修改并配置脚本

请使用 vim 或 nano 等工具来修改。

关于变量名的一些说明:

 

ENCRYPTFLG (加密FLG,true 为加密,false 为不加密,默认是加密)
BACKUPPASS (加密密码,重要,务必要修改)
LOCALDIR (备份目录,可自己指定)
TEMPDIR (备份目录的临时目录,可自己指定)
LOGFILE (脚本运行产生的日志文件路径)
MYSQL_ROOT_PASSWORD (MySQL/MariaDB/Percona 的 root 用户密码)
MYSQL_DATABASE_NAME (指定 MySQL/MariaDB/Percona 的数据库名,留空则是备份所有数据库)
※ MYSQL_DATABASE_NAME 是一个数组变量,可以指定多个。举例如下:

MYSQL_DATABASE_NAME[0]="phpmyadmin"
MYSQL_DATABASE_NAME[1]="test"

BACKUP (需要备份的指定目录或文件列表,留空就是不备份目录或文件)
※ BACKUP 是一个数组变量,可以指定多个。举例如下:

BACKUP[0]="/data/www/default/test.tgz"
BACKUP[1]="/data/www/default/test/"
BACKUP[2]="/data/www/default/test2/"

LOCALAGEDAILIES (指定多少天之后删除本地旧的备份文件,默认为 7 天)
DELETE_REMOTE_FILE_FLG (删除 Google Drive 或 FTP 上的备份文件 FLG,true 为删除,false 为不删除)

FTP_FLG (上传文件至 FTP 的 FLG,true 为上传,false 为不上传)
FTP_HOST (连接的 FTP 域名或 IP 地址)
FTP_USER (连接的 FTP 的用户名)
FTP_PASS (连接的 FTP 的用户的密码)
FTP_DIR (连接的 FTP 的远程目录,比如: public_html)

一些注意事项的说明:

1)脚本需要用 root 用户来执行;
2)脚本需要用到 openssl 来加密,请事先安装好;
3)脚本默认备份所有的数据库(全量备份);
4)备份文件的解密命令如下:

openssl enc -aes256 -in [ENCRYPTED BACKUP] -out decrypted_backup.tgz -pass pass:[BACKUPPASS] -d -md sha1

5)备份文件解密后,解压命令如下:

tar -zxPf [DECRYPTION BACKUP FILE]

解释一下参数 -P:
tar 压缩文件默认都是相对路径的。加个 -P 是为了 tar 能以绝对路径压缩文件。因此,解压的时候也要带个 -P 参数。

3、配置 gdrive 命令

gdrive 是一个命令行工具,用于 Google Drive 的上传下载等操作。官网网站:
https://github.com/prasmussen/gdrive

当然,你可以用以下的命令来安装 gdrive。

x86_64(64位):

wget -O /usr/bin/gdrive http://dl.lamp.sh/files/gdrive-linux-x64
chmod +x /usr/bin/gdrive

i386(32位)

wget -O /usr/bin/gdrive http://dl.lamp.sh/files/gdrive-linux-386
chmod +x /usr/bin/gdrive

然后,运行以下命令开始获取授权:

gdrive about

根据提示用浏览器打开 gdrive 给出的 URL,点击接受(Accept),然后将浏览器上显示出来的字符串粘贴回命令行里,完成授权。

4、运行脚本开始备份

./backup.sh

脚本默认会显示备份进度,并在最后统计出所需时间。
如果你想将脚本加入到 cron 自动运行的话,就不需要前台显示备份进度,只写日志就可以了。
这个时候你需要稍微改一下脚本中的 log 函数。

log() {
echo "$(date "+%Y-%m-%d %H:%M:%S")" "$1"
echo -e "$(date "+%Y-%m-%d %H:%M:%S")" "$1" >> ${LOGFILE}
}

改为:

log() {
echo -e "$(date "+%Y-%m-%d %H:%M:%S")" "$1" >> ${LOGFILE}
}

关于如何使用 cron 自动备份,这里就不再赘述了 以 CentOS 6 来举例说明。

修改文件 /etc/crontab,内容如下:

SHELL=/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
MAILTO=root
HOME=/root # For details see man 4 crontabs # Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
30 1 * * * root bash /root/backup.sh

以上表示,每天凌晨 1 点 30 分,root 用户执行一次 backup.sh 脚本。
注意:
一定要修改其中的 PATH 和 HOME 变量的值。
尤其是 HOME 变量,gdrive 命令能否正确执行,是要依赖于其配置文件的。默认用 root 配置的话,其配置文件夹应该是 /root/.gdrive/ ,所以要更改 HOME 的值。

backup.sh 代码如下所示:
#!/usr/bin/env bash
#
# Auto backup script
#
# Copyright (C) Teddysun <i@teddysun.com>
#
# URL: https://teddysun.com/469.html
#
# You must to modify the config before run it!!!
# Backup MySQL/MariaDB/Percona datebases, files and directories
# Backup file is encrypted with AES256-cbc with SHA1 message-digest (option)
# Auto transfer backup file to Google Drive (need install gdrive command) (option)
# Auto transfer backup file to FTP server (option)
# Auto delete Google Drive's or FTP server's remote file (option)
# [[ $EUID -ne ]] && echo "Error: This script must be run as root!" && exit ########## START OF CONFIG ########## # Encrypt flag (true: encrypt, false: not encrypt)
ENCRYPTFLG=true # WARNING: KEEP THE PASSWORD SAFE!!!
# The password used to encrypt the backup
# To decrypt backups made by this script, run the following command:
# openssl enc -aes256 -in [encrypted backup] -out decrypted_backup.tgz -pass pass:[backup password] -d -md sha1
BACKUPPASS="mypassword" # Directory to store backups
LOCALDIR="/root/backups/" # Temporary directory used during backup creation
TEMPDIR="/root/backups/temp/" # File to log the outcome of backups
LOGFILE="/root/backups/backup.log" # OPTIONAL: If you want backup MySQL database, enter the MySQL root password below
MYSQL_ROOT_PASSWORD="" # Below is a list of MySQL database name that will be backed up
# If you want backup ALL databases, leave it blank.
MYSQL_DATABASE_NAME[]="" # Below is a list of files and directories that will be backed up in the tar backup
# For example:
# File: /data/www/default/test.tgz
# Directory: /data/www/default/test
BACKUP[]="" # Number of days to store daily local backups (default days)
LOCALAGEDAILIES="" # Delete Googole Drive's & FTP server's remote file flag (true: delete, false: not delete)
DELETE_REMOTE_FILE_FLG=false # Upload to FTP server flag (true: upload, false: not upload)
FTP_FLG=false # FTP server
# OPTIONAL: If you want upload to FTP server, enter the Hostname or IP address below
FTP_HOST="" # FTP username
# OPTIONAL: If you want upload to FTP server, enter the FTP username below
FTP_USER="" # FTP password
# OPTIONAL: If you want upload to FTP server, enter the username's password below
FTP_PASS="" # FTP server remote folder
# OPTIONAL: If you want upload to FTP server, enter the FTP remote folder below
# For example: public_html
FTP_DIR="" ########## END OF CONFIG ########## # Date & Time
DAY=$(date +%d)
MONTH=$(date +%m)
YEAR=$(date +%C%y)
BACKUPDATE=$(date +%Y%m%d%H%M%S)
# Backup file name
TARFILE="${LOCALDIR}""$(hostname)"_"${BACKUPDATE}".tgz
# Encrypted backup file name
ENC_TARFILE="${TARFILE}.enc"
# Backup MySQL dump file name
SQLFILE="${TEMPDIR}mysql_${BACKUPDATE}.sql" log() {
echo "$(date "+%Y-%m-%d %H:%M:%S")" "$1"
echo -e "$(date "+%Y-%m-%d %H:%M:%S")" "$1" >> ${LOGFILE}
} # Check for list of mandatory binaries
check_commands() {
# This section checks for all of the binaries used in the backup
BINARIES=( cat cd du date dirname echo openssl mysql mysqldump pwd rm tar ) # Iterate over the list of binaries, and if one isn't found, abort
for BINARY in "${BINARIES[@]}"; do
if [ ! "$(command -v "$BINARY")" ]; then
log "$BINARY is not installed. Install it and try again"
exit
fi
done # check gdrive command
GDRIVE_COMMAND=false
if [ "$(command -v "gdrive")" ]; then
GDRIVE_COMMAND=true
fi # check ftp command
if ${FTP_FLG}; then
if [ ! "$(command -v "ftp")" ]; then
log "ftp is not installed. Install it and try again"
exit
fi
fi
} calculate_size() {
local file_name=$
local file_size=$(du -h $file_name >/dev/null | awk '{print $1}')
if [ "x${file_size}" = "x" ]; then
echo "unknown"
else
echo "${file_size}"
fi
} # Backup MySQL databases
mysql_backup() {
if [ -z ${MYSQL_ROOT_PASSWORD} ]; then
log "MySQL root password not set, MySQL backup skipped"
else
log "MySQL dump start"
mysql -u root -p"${MYSQL_ROOT_PASSWORD}" >/dev/null <<EOF
exit
EOF
if [ $? -ne ]; then
log "MySQL root password is incorrect. Please check it and try again"
exit
fi if [ "${MYSQL_DATABASE_NAME[*]}" == "" ]; then
mysqldump -u root -p"${MYSQL_ROOT_PASSWORD}" --all-databases > "${SQLFILE}" >/dev/null
if [ $? -ne ]; then
log "MySQL all databases backup failed"
exit
fi
log "MySQL all databases dump file name: ${SQLFILE}"
#Add MySQL backup dump file to BACKUP list
BACKUP=(${BACKUP[*]} ${SQLFILE})
else
for db in ${MYSQL_DATABASE_NAME[*]}
do
unset DBFILE
DBFILE="${TEMPDIR}${db}_${BACKUPDATE}.sql"
mysqldump -u root -p"${MYSQL_ROOT_PASSWORD}" ${db} > "${DBFILE}" >/dev/null
if [ $? -ne ]; then
log "MySQL database name [${db}] backup failed, please check database name is correct and try again"
exit
fi
log "MySQL database name [${db}] dump file name: ${DBFILE}"
#Add MySQL backup dump file to BACKUP list
BACKUP=(${BACKUP[*]} ${DBFILE})
done
fi
log "MySQL dump completed"
fi
} start_backup() {
[ "${BACKUP[*]}" == "" ] && echo "Error: You must to modify the [$(basename $0)] config before run it!" && exit log "Tar backup file start"
tar -zcPf ${TARFILE} ${BACKUP[*]}
if [ $? -gt ]; then
log "Tar backup file failed"
exit
fi
log "Tar backup file completed" # Encrypt tar file
if ${ENCRYPTFLG}; then
log "Encrypt backup file start"
openssl enc -aes256 -in "${TARFILE}" -out "${ENC_TARFILE}" -pass pass:"${BACKUPPASS}" -md sha1
log "Encrypt backup file completed" # Delete unencrypted tar
log "Delete unencrypted tar file: ${TARFILE}"
rm -f ${TARFILE}
fi # Delete MySQL temporary dump file
for sql in `ls ${TEMPDIR}*.sql`
do
log "Delete MySQL temporary dump file: ${sql}"
rm -f ${sql}
done if ${ENCRYPTFLG}; then
OUT_FILE="${ENC_TARFILE}"
else
OUT_FILE="${TARFILE}"
fi
log "File name: ${OUT_FILE}, File size: `calculate_size ${OUT_FILE}`"
} # Transfer backup file to Google Drive
# If you want to install gdrive command, please visit website:
# https://github.com/prasmussen/gdrive
# of cause, you can use below command to install it
# For x86_64: wget -O /usr/bin/gdrive http://dl.lamp.sh/files/gdrive-linux-x64; chmod +x /usr/bin/gdrive
# For i386: wget -O /usr/bin/gdrive http://dl.lamp.sh/files/gdrive-linux-386; chmod +x /usr/bin/gdrive
gdrive_upload() {
if ${GDRIVE_COMMAND}; then
log "Tranferring backup file to Google Drive"
gdrive upload --no-progress ${OUT_FILE} >> ${LOGFILE}
if [ $? -ne ]; then
log "Error: Tranferring backup file to Google Drive failed"
exit
fi
log "Tranferring backup file to Google Drive completed"
fi
} # Tranferring backup file to FTP server
ftp_upload() {
if ${FTP_FLG}; then
[ -z ${FTP_HOST} ] && log "Error: FTP_HOST can not be empty!" && exit
[ -z ${FTP_USER} ] && log "Error: FTP_USER can not be empty!" && exit
[ -z ${FTP_PASS} ] && log "Error: FTP_PASS can not be empty!" && exit
[ -z ${FTP_DIR} ] && log "Error: FTP_DIR can not be empty!" && exit local FTP_OUT_FILE=$(basename ${OUT_FILE})
log "Tranferring backup file to FTP server"
ftp -in ${FTP_HOST} >& >> ${LOGFILE} <<EOF
user $FTP_USER $FTP_PASS
binary
lcd $LOCALDIR
cd $FTP_DIR
put $FTP_OUT_FILE
quit
EOF
log "Tranferring backup file to FTP server completed"
fi
} # Get file date
get_file_date() {
#Approximate a -day month and -day year
DAYS=$(( $((#${YEAR}*)) + $((#${MONTH}*)) + $((#${DAY})) )) unset FILEYEAR FILEMONTH FILEDAY FILEDAYS FILEAGE
FILEYEAR=$(echo "$1" | cut -d_ -f2 | cut -c -)
FILEMONTH=$(echo "$1" | cut -d_ -f2 | cut -c -)
FILEDAY=$(echo "$1" | cut -d_ -f2 | cut -c -) if [[ "${FILEYEAR}" && "${FILEMONTH}" && "${FILEDAY}" ]]; then
#Approximate a -day month and -day year
FILEDAYS=$(( $((#${FILEYEAR}*)) + $((#${FILEMONTH}*)) + $((#${FILEDAY})) ))
FILEAGE=$(( #${DAYS} - #${FILEDAYS} ))
return
fi return
} # Delete Google Drive's old backup file
delete_gdrive_file() {
local FILENAME=$
if ${DELETE_REMOTE_FILE_FLG} && ${GDRIVE_COMMAND}; then
local FILEID=$(gdrive list -q "name = '${FILENAME}'" --no-header | awk '{print $1}')
if [ -n ${FILEID} ]; then
gdrive delete ${FILEID} >> ${LOGFILE}
log "Google Drive's old backup file name: ${FILENAME} has been deleted"
fi
fi
} # Delete FTP server's old backup file
delete_ftp_file() {
local FILENAME=$
if ${DELETE_REMOTE_FILE_FLG} && ${FTP_FLG}; then
ftp -in ${FTP_HOST} >& >> ${LOGFILE} <<EOF
user $FTP_USER $FTP_PASS
cd $FTP_DIR
del $FILENAME
quit
EOF
log "FTP server's old backup file name: ${FILENAME} has been deleted"
fi
} # Clean up old file
clean_up_files() {
cd ${LOCALDIR} || exit if ${ENCRYPTFLG}; then
LS=($(ls *.enc))
else
LS=($(ls *.tgz))
fi for f in ${LS[@]}
do
get_file_date ${f}
if [ $? == ]; then
if [[ ${FILEAGE} -gt ${LOCALAGEDAILIES} ]]; then
rm -f ${f}
log "Old backup file name: ${f} has been deleted"
delete_gdrive_file ${f}
delete_ftp_file ${f}
fi
fi
done
} # Main progress
STARTTIME=$(date +%s) # Check if the backup folders exist and are writeable
if [ ! -d "${LOCALDIR}" ]; then
mkdir -p ${LOCALDIR}
fi
if [ ! -d "${TEMPDIR}" ]; then
mkdir -p ${TEMPDIR}
fi log "Backup progress start"
check_commands
mysql_backup
start_backup
log "Backup progress complete" log "Upload progress start"
gdrive_upload
ftp_upload
log "Upload progress complete" clean_up_files ENDTIME=$(date +%s)
DURATION=$((ENDTIME - STARTTIME))
log "All done"
log "Backup and transfer completed in ${DURATION} seconds"

最后,欢迎交流和提出意见。

转载请注明:秋水逸冰 » 一键备份脚本backup.sh

一键备份脚本 backup.sh的更多相关文章

  1. mysqldump全备份脚本mysqlallbackup.sh

    库小,大概16G左右,每天增量很小,不到100M,所以用mysqldump每天全量备份,将备份结果信息发送到email通知DBA. mysqlallbackup.sh :MySQL DataBase ...

  2. RMAN多种备份脚本分享

    1.相关参数介绍: 命令行参数 描述 TARGET 为目标数据库定义的一个连接字符串,当连接到一个目标数据库时,该连续是SYSDBA连接.该用户拥有启动和关闭数据库的权利,必须属于OSDBA组,必须建 ...

  3. svn数据库自动备份脚本

    创建一个存放备份数据的路径 mkdir /data/svnbak -p 采用shell脚本的方式实现自动备份 #vim backup.sh #!/bin/bash log="/data/sv ...

  4. weblogic域备份脚本

    一直一来,由于空间问题,weblogic域很少备份,偶尔会手动备份一次,这运维做得不称职,今天有时间,写个小脚本来定时备份. 1.脚本备份文件目录结构 [weblogic@mylinux ~]$ tr ...

  5. 全网备份脚本rsync

    一,服务端配置 #!/bin/sh ######################################################### #by:kingle # #use: confi ...

  6. mysql自动备份脚本

    linux系统mysql5.6版本实现自动备份步骤 1.sudo mysql --help | grep my.cnf 查找my.cnf文件2.在文件中添加如下行实现免输入密码[mysqldump]u ...

  7. MySQL For Linux(CentOS/Ubuntu/Debian/Fedora/Arch)一键安装脚本(5.1-8.0)

    简介 很多童鞋不懂这么在Linux系统安装MySQL,网上大多数教程较复杂,不太适合小白安装,本教程提供一键安装脚本供大家使用,教大家怎么在Linux操作系统( 支持CentOS/Ubuntu/Deb ...

  8. 一个简单的RMAN自动备份脚本

    rman备份脚本: #!/bin/bashsource /home/oracle/.bash_profile rman target / << EOFrun {allocate chann ...

  9. LINUX 自动备份脚本文件

    首先我在/root/backup 目录下建立一个文件夹, #mkdir /root/backup/mysqlbackup 以后在每天五点钟,就会有一个文件保存在这里. 接着新建文件 #vim /roo ...

随机推荐

  1. Python中的矩阵、多维数组:Numpy

    Numpy 是Python中科学计算的核心库.它提供一个高性能多维数据对象,以及操作这个对象的工具.部分功能如下: ndarray, 具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组. 用于对 ...

  2. uva 1608 不无聊的序列

    uva 1608 不无聊的序列 紫书上有这样一道题: 如果一个序列的任意连续子序列中都至少有一个只出现一次的元素,则称这个序列时不无聊的.输入一个n个元素的序列,判断它是不是无聊的序列.n<=2 ...

  3. C++基本变量类型

    算数类型表 类型 含义 最小存储空间 取值范围 bool 布尔型 –   char 字符型 8位 -2^7 ~ 2^7-1 wchar_t 宽字符型 16位   short 短整型 16位 -2^15 ...

  4. JavaScript和jquery中的宽度

    Javascript: 网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight 网页可见区域宽: document ...

  5. CodeForces - 186A-Comparing Strings

    Some dwarves that are finishing the StUDY (State University for Dwarven Youngsters) Bachelor courses ...

  6. Duff and Meat(贪心)

    Duff is addicted to meat! Malek wants to keep her happy for n days. In order to be happy in i-th day ...

  7. maven插件: shade, assembly

    shade插件的作用: 通过版本的exclution无法解决jar冲突的问题, 解决方案是把依赖的包打到本model的jar中,打包的时候由mvn plugin自动修改代码中的依赖jar包名 relo ...

  8. 029 Divide Two Integers 两数相除

    不使用乘号,除号和取模符号将两数相除.如果溢出返回 MAX_INT.详见:https://leetcode.com/problems/divide-two-integers/description/ ...

  9. Harry And Biological Teacher 分块 + 字符串hash

    http://acm.hdu.edu.cn/showproblem.php?pid=5069 首先判断suffix和prefix最长多少可以直接暴力枚举长度然后 + hash可以立马判断是否相等,复杂 ...

  10. Linux中vim编辑器的缩进的功能键

    vim编程时,经常需要对代码进行缩进处理,以增加程序的可读性和后期的代码维护. 可以采用多种方式达到缩进的目的: 1) 命令模式(command mode) 2) Visual模式(visual mo ...