Skip to content

Instantly share code, notes, and snippets.

@grantnorwood
Forked from pacoorozco/wp-update.sh
Last active April 30, 2022 09:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grantnorwood/14612f596d96973b14caea41fd45f832 to your computer and use it in GitHub Desktop.
Save grantnorwood/14612f596d96973b14caea41fd45f832 to your computer and use it in GitHub Desktop.
Backup and update a Wordpress Site using wp-cli
#!/usr/bin/env bash
##########################################################################
# Shellscript : Backup and update WordPress using wp-cli
# Author : Grant Norwood <grantnorwood.com>
# Original Author : Paco Orozco <paco@pacoorozco.info>
# Requires : wp-cli
##########################################################################
# Changelog
# 20220430: 2.0
# Adds a user-specified option for forcing backup & updates
# 20170125: 1.0
# Adds a default option to upgrade only when it's needed.
# 20161220: 0.1
# Inital release
##########################################################################
##########################################################################
# Configuration Section
##########################################################################
#
##########################################################################
# DO NOT MODIFY BEYOND THIS LINE
##########################################################################
# Program name and version
PN=$( basename "$0" )
VER='1.0'
# Script exits immediately if any command within it exits with a non-zero status.
set -o errexit
# Script will catch the exit status of a previous command in a pipe.
set -o pipefail
# Script exits immediately if tries to use an undeclared variables.
set -o nounset
# Uncomment this to enable debug
# set -o xtrace
# Get data in dd-mm-yyyy format
TIMESTAMP=$( date +"%Y%m%d-%H%M" )
# Set verbose mode
VERBOSE=false
WP_PATH=""
BACKUP_PATH=""
NUM_OF_BACKUPS=0
WP_CLI="wp"
FORCE_BACKUP=false
WXR=false
# Ansi color code variables
red="\e[0;91m"
blue="\e[0;94m"
expand_bg="\e[K"
blue_bg="\e[0;104m${expand_bg}"
red_bg="\e[0;101m${expand_bg}"
green_bg="\e[0;102m${expand_bg}"
green="\e[0;92m"
white="\e[0;97m"
bold="\e[1m"
uline="\e[4m"
reset="\e[0m"
###
# Examples
###
# # horizontally expanded backgrounds
# echo -e "${blue_bg}${reset}"
# echo -e "${red_bg}${reset}"
# echo -e "${green_bg}${reset}"
# echo ""
# # colored text
# echo -e "${red}Hello World!${reset}"
# echo ""
# # bold colored text
# echo -e "${red}${bold}Hello World!${reset}"
# echo ""
# # underlined colored text
# echo -e "${red}${uline}Hello World!${reset}"
# echo ""
# # ansi across multiple lines
# echo -e "${green}This is a sentence across"
# echo "three lines to show how an ansi color"
# echo -e "works across multiple lines with echo.${reset}"
# echo ""
# # combining ansi in one line
# echo -e "${red}This sentence ${green}displays ${blue}ansi code used in ${white}${bold}combination.${reset}"
##########################################################################
# Functions
##########################################################################
function warn () {
if [ "${VERBOSE}" = true ]
then
if [ "$1" = "-n" ]
then
shift; echo -n "$@"
else
echo "$@"
fi
fi
}
function crit () {
local ERROR=0
[ "$1" = "-e" ] && shift; ERROR=$1; shift
echo >&2 -e "${PN}: $@"
[ ${ERROR} ] && exit ${ERROR}
}
function check-requirements () {
# Check if wp-cli is installed.
if ! hash ${WP_CLI} 2>/dev/null ; then
crit -e 1 "We require wp-cli.\nFor more info visit wp-cli.org or github.com/wp-cli/wp-cli/wiki."
fi
}
function usage () {
# Variables for formatting
local U=$(tput smul) # Underline
local RU=$(tput rmul) # Remove underline
local B=$(tput bold) # Bold
local N=$(tput sgr0) # Normal
cat <<-EOF
${B}Usage:${N}
${B}${PN}${N} -p ${U}directory${RU} [-b ${U}directory${RU}] [options]...
${B}Options:${N}
${B}-f${N} Force backup even if the WordPress site is updated
${B}-h${N} Display this help message
${B}-v${N} Enable verbose mode
${B}-p${N} ${U}directory${RU}
Path to WordPress files. This is a required flag.
${B}-b${N} ${U}backup_dir${RU}
Backup WP installation into a ${U}backup_dir${RU} before updating. Backs up
both the database and files. Will be stored in the following format:
${U}backup_directory${RU}
├── wp-backup_YYYY-MM-DD_HH:MM:SS
│ ├── database.sql
│ └── files.tar.gz
└── wp-backup...
Without this option the script will keep backups on ${U}directory/backups${RU}.
${B}-n${N} ${U}number${RU}
Number of backups to keep if ${B}-b${N} is specified. Useful to keep the
backups directory clean, in case this script is run as a cron job.
Without this option the script will keep unlimited backups.
${B}-w${N} Generate a wxr (WordPress Extended RSS) file if ${B}-b${N} is specified.
This file contains all your posts and is useful if you want to
quickly migrate to wordpress.com. Otherwise it is redundant as the
${B}-b${N} option already exports your database.
${B}Examples:${N}
${PN} ${B}-p${N} ${U}/var/www/wp${RU}
Minimal options. Will update WordPress installation in the specified
directory. Will backup in /var/www/wp/backups.
${PN} ${B}-p${N} ${U}/var/www/wp${RU} ${B}-b${N} ${U}~/backups${RU} ${B}-n${N} ${U}5${RU}
Same as above but now if there are old backups in the backups directory
the script will clean it up leaving only the 5 most recent ones.
If there are less than 5 backups, then nothing will happen.
EOF
}
function backup () {
echo ""
echo -e "${bold}Backing up your site's database & files ...${reset}"
local BACKUP_PATH_TIMESTAMP="${BACKUP_PATH}/wp-backup_${TIMESTAMP}"
mkdir -p ${BACKUP_PATH_TIMESTAMP}
echo -e " • Backing up the database ...${reset}"
${WP_CLI} db export ${BACKUP_PATH_TIMESTAMP}/db.sql
echo -e " • Backing up site directory ...${reset}"
tar -czf ${BACKUP_PATH_TIMESTAMP}/www.tar.gz \
--exclude='**/wp-content/upgrade' \
--exclude='**/wp-content/uploads/backupbuddy_backups' \
--exclude='**/wp-content/uploads/pb_backupbuddy' \
${WP_PATH} \
2>/dev/null
if [ $WXR = true ] ; then
${WP_CLI} export --dir=${BACKUP_PATH_TIMESTAMP}
fi
echo -e "✅ ${green}Done!${reset}"
}
function update () {
echo ""
echo -e "${bold}Running WordPress updates ...${reset}"
echo -e " • Updating core ...${reset}"
${WP_CLI} core update
echo -e " • Updating plugins ...${reset}"
${WP_CLI} plugin update --all
echo -e " • Updating themes ...${reset}"
${WP_CLI} theme update --all
echo -e "✅ ${green}Done!${reset}"
}
function exit_if_update_is_not_needed () {
local NEED_CORE_UPDATE=$( ${WP_CLI} core check-update --format=count )
local NEED_PLUGIN_UPDATE=$( ${WP_CLI} plugin list --update=available --format=count )
if [ -z "${NEED_CORE_UPDATE}" ] && [ "${NEED_PLUGIN_UPDATE}" = "0" ] ; then
warn "🤷‍♂️ This WordPress site is updated. Nothing to do."
exit 0
fi
echo -e "👉 Updates are available.${reset}"
# warn "There are some updates available."
}
function cleanup () {
if [ "${NUM_OF_BACKUPS}" -gt "0" ] ; then
echo -e "🗑 ${$bold}Deleting backups greater than ${NUM_OF_BACKUPS} ...${reset}"
ls -td ${BACKUP_PATH}/* | awk -v n=${NUM_OF_BACKUPS} 'NR>n' | xargs -r rm -r
echo -e "✅ ${green}Done!${reset}"
fi
}
function finish () {
echo ""
echo -e "🏁 ${bold}Finished!${reset}"
echo ""
}
##########################################################################
# Main
##########################################################################
# Resetting OPTIND is necessary if getopts was used previously in the script.
OPTIND=1
# Process command line options
while getopts ":hvfwp:b:n:" opt; do
case $opt in
h)
usage
;;
p)
WP_PATH=${OPTARG}
;;
b)
BACKUP_PATH=${OPTARG}
;;
n)
if [ ! $( echo ${OPTARG} | egrep ^[[:digit:]]+$ ) ] ; then
crit -e 1 "Bad number of backups to keep"
else
NUM_OF_BACKUPS=${OPTARG}
fi
;;
w)
WXR=true
;;
v)
VERBOSE=true
;;
f)
FORCE_BACKUP=true
;;
?)
crit -e 1 "Invalid option: -${OPTARG}"
;;
:)
crit -e 1 "Option -${OPTARG} requires and arguement"
;;
esac
done
# Shift off the options and optional --.
shift "$((OPTIND - 1))"
# Run appropriate functions based on options provided
if [ -z "${WP_PATH}" ] ; then
usage
exit 1
fi
# Set a default Backup path if it hasn't beed defined
BACKUP_PATH="${BACKUP_PATH:-${WP_PATH}/backups}"
# Set the wp-cli command with WP path
WP_CLI="wp --path=${WP_PATH}"
check-requirements
if [ $FORCE_BACKUP != true ] ; then
# Checks if WordPress update is needed.
exit_if_update_is_not_needed
exit 1
fi
# We need to update someting.
backup
update
cleanup
finish
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment