WordPress.org

Codex

User:AskApache/Shell Script for Automatic Encrypted Backups

This article is a ROUGH DRAFT. The author is still working on this document, so please do not edit this without the author's permission. The content within this article may not yet be verified or valid. This information is subject to change.


Update

The following is a single function that creates both an mysql dump and a tar+gzipped backup.

bk_askapache ()
{
    local _N _U _P _H FS FT TD WP;
    FT=`date +$HOME/.bk/askapache-%m-%d-%g-%H%M.tgz`;
    FS=`date +$HOME/.bk/askapache-%m-%d-%g-%H%M.sql`;
    TD=$HOME/public_html/askapache/;
    WP=$TD/wp-config.php;
    ( cd $TD || {
        echo "bad $TD" && return 2
    };
    eval $(sed -n "s/^d[^D]*DB_\([NUPH]\)[ASO].*',[^']*'\([^']*\)'.*/_\1='\2'/p" $WP);
    mysqldump --opt --add-drop-table -u$_U -p$_P -h$_H $_N > $FS;
    tar --ignore-failed-read -czPf $FT $TD )
}



[1]

#!/bin/bash
# SiteBack Version 3.1, 2008-07-04
# GNU Free Documentation License 1.2
# 07-04-08 - AskApache (www.askapache.com)
umask 022

### SHELL OPTIONS
set +o noclobber # allowed to clobber files
set +o noglob # globbing on
set +o xtrace # change to - to enable tracing
set +o verbose # change to - to enable verbose debugging
set -e # abort on first error

shopt -s extglob



###########################################################################--=--=--=--=--=--=--=--=--=--=--#
###
### SETTINGS
###
###########################################################################==-==-==-==-==-==-==-==-==-==-==#

DT=$(date +%x); DT=${DT//\/}
DTX=$(date +%x-%H%M); DTX=${DTX//\/}
BDIR=${HOME}/backups
RUN_FILE=${BDIR}/$$.bk.log
MY_CONFIG=".sbackup"
DOMAIN=;DB_NAME=;DB_USER=;DB_PASSWORD=;DB_HOST=;WP_CONFIG=;SQL_DEST=;ARC_DEST=;ENCRYPT_USER=
E_SUCCESS=0;E_YN=0;E_YES=251;E_NO=250;E_RETURN=65;C0=;C1=;C2=;C3=;C4=;C5=;C6=;C7=;C8=;C9=




###########################################################################--=--=--=--=--=--=--=--=--=--=--#
###
### FUNCTIONS
###
###########################################################################==-==-==-==-==-==-==-==-==-==-==#

#--=--=--=--=--=--=--=--=--=--=--#
# script_title
#==-==-==-==-==-==-==-==-==-==-==#
function script_title(){
 # SET WINDOW TITLE AND COLORS IF CLIENT CAPABLE
 case ${TERM:-dummy} in
  xterm*|vt*|ansi|rxvt|gnome*)
  C0="\033[0m";C1="\033[1;30m";C2="\033[1;32m";C3="\033[0;32m";C4="\033[1;37m"
  C5="\033[0;36m";C6="\033[1;35m";C7="\033[0;37m";C8="\033[30;42m";C9="\033[1;36m"
 esac	
 echo -e "${C1} __________________________________________________________________________ "
 echo -e "| ${C2}             ___       __    ___                 __             ${C1}         |"
 echo -e "| ${C2}            / _ | ___ / /__ / _ | ___  ___ _____/ /  ___        ${C1}         |"
 echo -e "| ${C2}           / __ |(_-</  '_// __ |/ _ \/ _ \`/ __/ _ \/ -_)       ${C1}         |"
 echo -e "| ${C3}          /_/ |_/___/_/\_\/_/ |_/ .__/\_,_/\__/_//_/\__/        ${C1}         |"
 echo -e "| ${C3}                               /_/                              ${C1}         |"
 echo -e "|                                                                          |"
 echo -e "|                 ${C4} SITE BACKUP SCRIPT Version 3.1 ${C1}                         |"
 echo -e "${C1} __________________________________________________________________________ ${C0} \n\n"
}


#--=--=--=--=--=--=--=--=--=--=--#
# pm
#==-==-==-==-==-==-==-==-==-==-==#
function pm(){
 START=$(date +%s) && touch ${RUN_FILE}
 case "${2:-title}" in
  "title") echo -en "\n\n${C2}>>> ${C4}${1} ${C0} \n\n"; ;;
   "info") echo -e "${C6}=> ${C4}${1} ${C0}"; ;;
   "item") echo -e "${C4}-- ${C0}${1} "; ;;
 esac
}



#--=--=--=--=--=--=--=--=--=--=--#
# yes_no
#==-==-==-==-==-==-==-==-==-==-==#
function yes_no(){
 local ans
 echo -en "${1} [y/n] " ; read -n 1 ans
 case "$ans" in
  n|N) E_YN=$E_NO ;;
  y|Y) E_YN=$E_YES ;;
 esac
}


#--=--=--=--=--=--=--=--=--=--=--#
# do_sleep
#==-==-==-==-==-==-==-==-==-==-==#
function do_sleep (){ 
 local END DIFF
 echo -en "${C5}${3:-.}"; while [ -r "$RUN_FILE" ]; do sleep ${2:-3}; echo -en "${3:-.}"; done;
 echo -e "${C0}"; sleep 1; END=$(date +%s);DIFF=$(( $END - $START ))
 echo -e "\n${C8} COMPLETED IN ${DIFF} SEC ${C0} \n\n"; sleep 1; 
 return 0; 
}



#--=--=--=--=--=--=--=--=--=--=--#
# get_settings
#==-==-==-==-==-==-==-==-==-==-==#
function get_settings(){
 local cha HOSTED_SITES G
 clear; script_title
 if [[ -r "$MY_CONFIG" ]]; then
  OIFS=$IFS; while IFS=: read DOMAIN DOMAINROOT WP_CONFIG ENCRYPT_USER; do
   DOMAIN=${DOMAIN}; DOMAINROOT=${DOMAINROOT}; WP_CONFIG=${WP_CONFIG}; ENCRYPT_USER=${ENCRYPT_USER}; E_YN=$E_YES; break
  done <${MY_CONFIG}; IFS=$OIFS
 else
 echo -en "\n What domain would you like to backup?  "; read -e DOMAIN; echo
 until [ -d "$DOMAINROOT" ]; do echo -en "\n Where is the domain root?  "; read -e DOMAINROOT; echo; done
 [[ -r "$DOMAINROOT/wp-config.php" ]] && WP_CONFIG=$DOMAINROOT/wp-config.php
 until [[ -r "$WP_CONFIG" ]]; do echo -en "\n Where is the wp-config.php file?  "; read -e WP_CONFIG; echo; done
 echo -en "\n What userid to use for encryption?  "; read -e ENCRYPT_USER; echo
 fi

 [[ -r "$WP_CONFIG" ]] && G=$(sed -e "/define('DB_\(NAME\|USER\|PASSWORD\|HOST\)/!d" \
 -e "s/[^']*'DB_\(NAME\|USER\|PASSWORD\|HOST\)'[^']*'\([^']*\)'.*$/DB_\1='\2';/g" ${WP_CONFIG}) && eval $G;
 mkdir -p ${BDIR}/${DOMAIN}
 SQL_DEST=${BDIR}/${DOMAIN}/${DOMAIN}-${DT}.sql;	[[ -r "${SQL_DEST}.asc" ]] && SQL_DEST=${BDIR}/${DOMAIN}/${DOMAIN}-${DTX}.sql
 ARC_DEST=${BDIR}/${DOMAIN}/${DOMAIN}-${DT}.tgz; [[ -r "${ARC_DEST}.asc" ]] && ARC_DEST=${BDIR}/${DOMAIN}/${DOMAIN}-${DTX}.tgz

 if [[ "$E_YN" != "$E_YES" ]]; then
  for a in "DOMAIN" "DOMAINROOT" "WP_CONFIG" "ENCRYPT_USER" "DB_NAME" "DB_USER" "DB_PASSWORD" "DB_HOST"; do echo -e "${a}: ${!a}"; done
  echo; yes_no "ARE THESE SETTINGS CORRECT"
 fi
 
 while [[ "$E_YN" != "$E_YES" ]]; do
  for a in "DOMAIN" "DOMAINROOT" "WP_CONFIG" "ENCRYPT_USER" "DB_NAME" "DB_USER" "DB_PASSWORD" "DB_HOST"; do
   echo -en "\n (Enter for Default: ${!a} )\n ${a}:> "
   read -e cha; echo; [[ ${#cha} -gt 2 ]] && eval "$a"=$cha
  done
  yes_no "ARE THESE SETTINGS CORRECT"
 done
 	
 echo -e "${DOMAIN}:${DOMAINROOT}:${WP_CONFIG}:${ENCRYPT_USER}" > $MY_CONFIG
}




############################################################################################################
###
### MAIN CODE
###
############################################################################################################

#=# MAKE MAIN SCRIPT NICE  
renice 19 -p $$ &>/dev/null

get_settings

pm "CREATING SQL BACKUP"
mysqldump --opt -u${DB_USER} -p${DB_PASSWORD} -h ${DB_HOST} -r ${SQL_DEST} \
--add-drop-table ${DB_NAME} 1>&2 &>/dev/null && sleep 2 1>&2 &>/dev/null && rm ${RUN_FILE} 2>&1& 
do_sleep 1 1 ":"


pm "ENCRYPTING SQL BACKUP"
gpg --armor --recipient ${ENCRYPT_USER} --output ${SQL_DEST}.asc --encrypt ${SQL_DEST} \
1>&2 &>/dev/null && sleep 2 1>&2 &>/dev/null && rm ${RUN_FILE} 2>&1& 
do_sleep 1 1 ":"; rm ${SQL_DEST}


pm "CREATING ARCHIVE BACKUP"
tar -czf ${ARC_DEST} . 1>&2 &>/dev/null && rm ${RUN_FILE} 2>&1& 
do_sleep 1 5 ":"


pm "ENCRYPTING ARCHIVE BACKUP"
gpg --armor --recipient ${ENCRYPT_USER} --output ${ARC_DEST}.asc --encrypt ${ARC_DEST} \
1>&2 &>/dev/null && rm ${RUN_FILE} 2>&1& 
do_sleep 1 1 ":"; rm ${ARC_DEST}


echo -e "${C1} __________________________________________________________________________ "
echo -e "|                                                                          |"
echo -e "|                 ${C4} COMPLETED SUCCESSFULLY ${C1}                                 |"
echo -e "${C1} __________________________________________________________________________ ${C0} \n\n"

exit $?