Shell Script for Automating WordPress updates for multiple blogs
Many moons ago I read Joost de Valk’s blog post about upgrading and installing WordPress from SVN. Since then, every blog I maintain I use the WordPress svn repository to check out, and to update using the simple command of “svn sw“.
But even with that ease, it can get a bit tedious to upgrade 10 blogs, for instance.
So, as all “script writers” that are in between TV Series do, I wrote a script to automate this.
To run this script, there are 2 critical requirements:
- You have access to the command line on your server (SSH access)
- Your WordPress directories were checked out of SVN, and so contain all the required “.svn” directories.
So, just in time for WordPress 2.7, which has the ability to update at the click of a button from the admin panel, here’s my script.
A basic rundown of what it does:
- Reads through a text file that you need to create containing the following 3 pieces of info, separated by colons (:)
- Your site URL without http://. Example: www.geniosity.co.za/musings
- The directory your site is in. Example: /path/to/your/site/dir/home/james123/public_html/musings
- The first part of the tar file name that will be created with your backup. Example: mus
Here’s what it might look like with the above info:
www.geniosity.co.za/musings:/home/james123/public_html/musings:mus
Setup and Execution of the script
So, your steps to getting this to run successfully are:
1 – Create the text file containing a list of all your sites and their relevent directories, in the above format. 1 record per site.
2 – Copy the script below to a relevant directory on your server, and give it executable permissions
3 – Read the “INITIAL SETUP” section just below “YOU MUST CHANGE THESE SETTINGS” near the top of the script, and create any directories that are needed in this section.
4 – Update the section where it says “YOU MUST CHANGE THESE SETTINGS” with the directories and variabls that are required.
5 – Run the script. I recommend using the following command:
nohup scriptname.sh &
This will run it in the background, and if you get disconnected for some reason while it’s running, it will continue in the background.
The benefits of this script
The 2 main benefits of this script are:
- Speed and ease of upgrading multiple blogs. As Matt Mullenweg mentioned on a WordPress Podcast episode while being interviewed by Charles Stricklin, if it takes you more than 2 minutes to upgrade your blog, there’s a problem.
- The second benefit is that this script sends you an email when it completes with the log files generated, as well as the Upgrade Link so you can just click it to upgrade the Database if required.
Other notes on this script
Please note, this script does NOT upgrade or backup your blog’s database. I recommend the “WordPress Database Backup” Plugin for that.
Also, I cannot guarantee it works for you. As I mentioned, I have tried this on 2 different servers with 2 different hosts, and it worked 100% there. But, for safety’s sake, do a manual backup the first time to ensure it all goes as planned.
And, if you’re wondering why I have all the extra brackets in the script, it’s because of the cool code-folding capabilities in jEdit, the Programmer’sText editor I use. For a screen shot of this, take a look at the bottom of this post.
The WordPress Upgrade Script
If you have any changes or recommendations, feel free to let me know in the comments.
#!/bin/bash
################################################################################
# #
#{-------------------------- wpUpgrade.sh -------------------------------- #
# #
# This script will go through a list of your WordPress websites that are #
# hosted on the same server, and update them using SVN (if they were initially#
# installed using SVN). #
# #
# Please ensure that you have set the carious Variables in the INITIAL SETUP #
# section. #
# #
# The SITE_INFO variable must point to a text file containing records in the #
# following format separated by colons (":") #
# #
# www.yoursite.com:/path/to/your/site/dir:filename #
# #
# For example: #
# #
# www.geniosity.co.za/musings:/home/james123/public_html/musings:musings #
# #
# The last field is the first part of the tar file name that will be generated.#
# For example: musings.20081024_1233.tar.bz2 #
# #
# #
#==============================================================================#
# #
# MODIFICATION LOG #
# #
# DATE DEVELOPER VERSION DESCRIPTION #
# ---------- ----------- -------- -------------------------------------------- #
# 2008/10/24 J. McMullan Script Written. #
# #
##############################################################################}#
################################################################################
#{--- INITIAL SETUP...
#----------------------
#--- YOU MUST CHANGE THESE SETTINGS
#------
#- The version of WordPress you are upgrading to
#- Example: "2.6.5"
NEW_VERSION_OF_WORDPRESS="2.6.5"
#- A temporary location for script output
#- Example: /home/userid/tmp
TEMP_DIR=/home/geniosit/tmp
#- A Directory where you want to place the backup files created
#- Example: /home/userid/backups
BACKUP_DIR=/home/geniosit/backups
#- A Directory where this script will output the logs
#- Example: /home/userid/logoutput
LOGS_DIR=/home/geniosit/scriptsoutput
#- The text file containing the list of WordPress sites and their directories
#- Example: /home/userid/scripts/wpsites.txt
SITE_INFO=/home/geniosit/scripts/wpdirs.txt
#- The email address where you will receive your messages from the script
EMAIL_ADDRESS="geniosity@gmail.com"
#- If you want to skip making backups (NOT recommended), change this to TRUE
SKIP_BACKUPS=FALSE
#------
#}--- END INITIAL SETUP...
################################################################################
################################################################################
#==== YOU DON'T NEED TO CHANGE ANYTHING PAST THIS POINT
#=======================================================
################################################################################
#{--- VARIABLES
#------
#------------------
#{General Variables
#---
THIS_SCRIPT_NAME=`basename $0`
RIGHT_NOW=`date +%Y%m%d_%H%M%S`
LOG_FILE=$LOGS_DIR/$THIS_SCRIPT_NAME.$RIGHT_NOW.log
WORDPRESS_SVN_DIRECTORY="http://svn.automattic.com/wordpress/tags"
#}----------------------------
#------------------
#{ERROR Variables
#---
errorLocation=
errorCode=
errorMessage=
#}----------------------------
#------------------------
#--- END VARIABLES SETUP
#}----------------------------
################################################################################
################################################################################
#{--- FUNCTIONS
#------
#-----------------------------------------------------
# Functions for logging output
#----------
function logtext {
RIGHT_NOW=`date +%Y%m%d_%H%M%S`
echo "$RIGHT_NOW: $1" | tee --append $LOG_FILE
}
function logsep {
echo "--------------------------------------------" | tee --append $LOG_FILE
}
#-----------------------------------------------------
# Functions for sending mails
#----------
function setupMailEnv {
logtext "In Function: setupMailEnv"
TEMP_MAIL_FILE=$TEMP_DIR/$THIS_SCRIPT_NAME.mail
>$TEMP_MAIL_FILE
}
function createMailFile {
logtext "In Function: createMailFile"
MAIL_DATE_TIME=`date +%Y%m%d_%H%S`
echo "$MAIL_DATE_TIME: $*" >> $TEMP_MAIL_FILE
}
function sendTheMail {
logtext "In Function: sendTheMail"
logtext "TEMP_MAIL_FILE=$TEMP_MAIL_FILE ++ THIS_SCRIPT_NAME=$THIS_SCRIPT_NAME ++ EMAIL_ADDRESS=$EMAIL_ADDRESS"
cat $TEMP_MAIL_FILE | mailx -s "Output from $THIS_SCRIPT_NAME" $EMAIL_ADDRESS
}
#-----------------------------------------------------
# Function to validate Required Variables
#----------
function validateRequiredVariables {
if [[ -z $NEW_VERSION_OF_WORDPRESS ]]; then
errorLocation="In Function: validateRequiredVariables"
errorCode=90
errorMessage="The NEW_VERSION_OF_WORDPRESS variable has not been set. Please ensure this is set to the latest version of WordPress."
logSendErrorMessages
exit $errorCode
fi
if [[ -z $TEMP_DIR ]]; then
errorLocation="In Function: validateRequiredVariables"
errorCode=91
errorMessage="The TEMP_DIR variable has not been set. Please ensure this is set to a valid directory before proceeding."
logSendErrorMessages
exit $errorCode
fi
if [[ -z $LOGS_DIR ]]; then
errorLocation="In Function: validateRequiredVariables"
errorCode=92
errorMessage="The LOGS_DIR variable has not been set. Please ensure this is set to a valid directory for the log files."
logSendErrorMessages
exit $errorCode
fi
if [[ -z $SITE_INFO ]]; then
errorLocation="In Function: validateRequiredVariables"
errorCode=93
errorMessage="The SITE_INFO variable has not been set. Please ensure this is set the full path and file name for the file containing your list of sites."
logSendErrorMessages
exit $errorCode
fi
if [[ ! -s $SITE_INFO ]]; then
errorLocation="In Function: validateRequiredVariables"
errorCode=94
errorMessage="It looks like you settings file is empty (or doesn't exist). Please check that the file $SITE_INFO is valid (and that the SITE_INFO variable is set correctly)."
logSendErrorMessages
exit $errorCode
fi
if [[ -z $EMAIL_ADDRESS ]]; then
errorLocation="In Function: validateRequiredVariables"
errorCode=95
errorMessage="The EMAIL_ADDRESS variable has not been set. This script needs an email address to notify you when upgrades are complete or if there are any errors.."
logSendErrorMessages
exit $errorCode
fi
}
#-----------------------------------------------------
# Function to log and send error message
#----------
function logSendErrorMessages {
logtext "ISSUE IN SECTION: $errorLocation"
logtext "ERROR CODE: $errorCode"
logtext "ERROR MESSAGE: $errorMessage"
setupMailEnv
createMailFile "ISSUE IN SECTION: $errorLocation"
createMailFile "ERROR CODE: $errorCode"
createMailFile "ERROR MESSAGE: $errorMessage"
sendTheMail
}
#-----------------------------------------------------
# Function to send upgrade link and message
#----------
function sendUpgradeLink {
logtext "SITE: $WP_SITE"
logtext "MESSAGE: UPGRADED SUCCESSFULLY!"
logtext "UPGRADE LINK: http://$WP_SITE/wp-admin/upgrade.php"
setupMailEnv
createMailFile "SITE: $WP_SITE"
createMailFile "MESSAGE: UPGRADED SUCCESSFULLY!"
createMailFile "UPGRADE LINK: http://$WP_SITE/wp-admin/upgrade.php"
sendTheMail
}
#-----------------------------------------------------
# Function to send the log file by mail
#----------
function sendLogFile {
logtext "About to send log file by mail"
setupMailEnv
cat $LOG_FILE >> $TEMP_MAIL_FILE
sendTheMail
}
#-----------------------------------------------------
# Function to log and send error message
#----------
function backupTheDirectory {
logtext "In function: backupTheDirectory"
if [[ -z $WP_DIR || -z $WP_TAR_FILE ]]; then
errorLocation="In Function: backupTheDirectory"
errorCode=1
errorMessage="Variables WP_DIR and WP_TAR_FILE are not set correctly.++ WP_SITE=$WP_SITE ++ WP_DIR=$WP_DIR ++ WP_TAR_FILE=$WP_TAR_FILE ++ Ensure the settings file contains proper records"
logSendErrorMessages
return $errorCode
fi
if [[ ! -e $BACKUP_DIR ]]; then
errorLocation="In Function: backupTheDirectory"
errorCode=2
errorMessage="Backup directory does not exist! Please ensure that the directory $BACKUP_DIR exists."
logSendErrorMessages
return $errorCode
fi
if [[ ! -w $BACKUP_DIR ]]; then
errorLocation="In Function: backupTheDirectory"
errorCode=3
errorMessage="Backup directory is not writable! Please ensure that the directory $BACKUP_DIR has write permissions."
logSendErrorMessages
return $errorCode
fi
if [[ ! -e $LOGS_DIR ]]; then
errorLocation="In Function: backupTheDirectory"
errorCode=4
errorMessage="Logs directory does not exist! Please ensure that the directory $LOGS_DIR exists."
logSendErrorMessages
return $errorCode
fi
if [[ ! -w $LOGS_DIR ]]; then
errorLocation="In Function: backupTheDirectory"
errorCode=5
errorMessage="Logs directory is not writable! Please ensure that the directory $LOGS_DIR has write permissions."
logSendErrorMessages
return $errorCode
fi
if [[ ! -e $WP_DIR ]]; then
errorLocation="In Function: backupTheDirectory"
errorCode=6
errorMessage="WP_DIR directory does not exist! Please ensure that the directory $WP_DIR exists."
logSendErrorMessages
return $errorCode
fi
tar cvfj $BACKUP_DIR/$WP_TAR_FILE $WP_DIR >> $LOG_FILE
if [[ $? -gt 0 ]]; then
errorLocation="In Function: backupTheDirectory"
errorCode=$?
errorMessage="Problem creating tar file.++ WP_TAR_FILE=$WP_TAR_FILE ++ WP_DIR=$WP_DIR ++ LOG_FILE=$LOG_FILE"
logSendErrorMessages
return $errorCode
fi
}
#------------------------
#}--- END FUNCTIONS SETUP
################################################################################
clear
logtext "**********************************************************"
logtext "**** STARTING WORDPRESS UPDATE SCRIPT ***"
logtext "**********************************************************"
validateRequiredVariables
for WP_RECORD in `cat $SITE_INFO`;
do
WP_SITE=`echo $WP_RECORD | awk -F: '{print $1}'`
WP_DIR=`echo $WP_RECORD | awk -F: '{print $2}'`
WP_BACKUP_FILE=`echo $WP_RECORD | awk -F: '{print $3}'`
RIGHT_NOW=`date +%Y%m%d_%H%M%S`
WP_TAR_FILE=$WP_BACKUP_FILE.$RIGHT_NOW.tar.bz2
logsep
logtext "Processing site: $WP_SITE"
logtext "Processing directory: $WP_DIR"
if [[ $SKIP_BACKUPS != TRUE ]]; then
logtext "About to do backup for $WP_SITE"
logtext "tar file will be: $WP_TAR_FILE"
backupTheDirectory
if [[ $? -gt 0 ]]; then
logtext "There was a problem doing the backups for site: $WP_SITE. EXITING!"
sendLogFile
exit $?
fi
logtext "Finished doing backups."
fi
logsep
logtext "Starting upgrades"
logtext "Checking the WP_DIR exists. ($WP_DIR)"
if [[ ! -e $WP_DIR ]]; then
errorLocation="Checking WP_DIR exists."
errorCode=10
errorMessage="WP_DIR directory does not exist! Please ensure that the directory $WP_DIR exists. EXITING!"
logSendErrorMessages
sendLogFile
exit $errorCode
fi
logtext "Checking the WP_DIR has write permissions"
if [[ ! -w $WP_DIR ]]; then
errorLocation="Checking the WP_DIR has write permissions"
errorCode=11
errorMessage="Logs directory is not writable! Please ensure that the directory $WP_DIR has write permissions. EXITING!"
logSendErrorMessages
sendLogFile
exit $errorCode
fi
cd $WP_DIR
if [[ $? -gt 0 ]]; then
errorLocation="Changing directory to $WP_DIR"
errorCode=12
errorMessage="Could not change directory to $WP_DIR! EXITING!"
logSendErrorMessages
sendLogFile
exit $errorCode
fi
svn sw $WORDPRESS_SVN_DIRECTORY/$NEW_VERSION_OF_WORDPRESS >> $LOG_FILE
if [[ $? -gt 0 ]]; then
errorLocation="Running svn sw command in $WP_DIR"
errorCode=13
errorMessage="Problem running svn sw command in $WP_DIR! EXITING!"
logSendErrorMessages
sendLogFile
exit $errorCode
fi
sendUpgradeLink
done
logsep
logtext "FINISHED RUNNING UPGRADES"
sendLogFile
The jEdit screenshot


