Upgrade your WordPress sites in 5 Seconds
THIS ARTICLE IS OUT DATED. Please see: http://www.TheCodeCave.com/EasyWPUpdate for the current release.
Well I’ve upgraded the 35 Second upgrade script significantly for this release.
Here’s a summary of the new features:
- Customizable options at the top of the script
- Works for unlimited numbers of blogs with just updating the header
- Optionally performs Web update steps as well
- Optionally performs backups of all WP related files
- DISABLED: Performs a Database Backup
- Backups are to a directory of your choosing suffixed with “today’s” date
- Can now upgrade blogs in a WordPress directory or any other
- Respects the tmp directory on your server
- Can be modified to perform nightly refresh of all blogs from a local tarball
- Can be customized to retrieve beta releases
- Can be customized to retrieve from WP.org’s archive folder
This hasn’t had a lot of testing yet outside of my blogs, but it has worked BEAUTIFULLY for me and as you can see I am running Version 2.0.6 thanks to spending 5 seconds this morning to update all of my blogs.
Here is the text to download: (link)
Perhaps the easiest way to get the file is to telnet into your account and run this line:
wget http://www.thecodecave.com/downloads/tcc_wp_upgrade
Then give yourself execute permissions on the script, choose your own or run this:
chmod +x tcc_wp_upgrade
If you get errors, remember that you might be dealing with passing the script through Windows and may have tacked on an extra CR at then end of each line… You should be able to fix that by using an SED command something like this
tr -d ‘\r’ tcc_wp_upgrade > xx && mv -f xx tcc_wp_upgrade
(Thanks to Prec on FreeNode #SED)
Then edit the file to your specifications using VI or whatever. I use NetDrive to make my website Drive X on all of my machines and then use Notepad2.exe to edit it and enforce the Unix line endings.
Right now I REALLY would like to have only proficient people run this script. It has only been tested on my sites.
This script messes with your files. If something really horrible goes wrong, you could lose information. I’ve done my best to ensure this doesn’t happen, but literally everything I know about bash I learned in the last month writing this script. A good programmer can go from any language to any language with relative ease (and bash IS a language), but we can’t know everything about how it works on all systems. That only comes with experience.
So I’ve got a bigggg scary message at the front of the script. It’s scarier than it needs to be, or I wouldn’t have the confidence to release the script at all. But it spells out in no uncertain terms the risks of running ANY unfamiliar script (not just mine) on your active site :
# Indemnity –
# Use this file at your own risk. I’m not going to deliberately hack
# your server, but others might. This is a shell script. Very bad
# things can happen. I am relatively new to *nix scripts. So
# I’ve had others review this script. But NONE of this guarantees
# things won’t go wrong or that this script is unchanged. Only
# use this script IF you’ve gotten it from TheCodeCave.com or another
# site you trust.
#
# THIS SCRIPT SHOULD BE USED AT YOUR OWN RISK. It can erase hours of
# hard work put into your site. Before using this script it is
# required that you review and understand every line and vouch for
# its safety. If you are not comfortable with this, don’t run this
# script. I have one host that I can test this on. Only you can say
# that this script will not do irreparable harm to your host if you
# use it.
#
# YOU are responsible for YOUR site. Learn how to protected it and
# understand what every line of code does before you call it.
When you run this script, please come back here and report your results.
Thanks!
Here’s the source for those that want to see it online:
[sh]
#!/bin/bash
# *************************************************************************
# UpdateWP ver 2.0 alpha 3 01/Aug/2006
# Written by Brian Layman
#
# A unix shell script to update multiple WordPress blogs to the current
# stable release.
#
# Usage: (A full instruction set is at https://thecodecave.com/article300)
# Browse out to www.TheCodeCave.com and get the latest
# Customize the “Configuration variables” found below
# Use chmod to grant yourself execute status on the script
# Run the program
#
# You can use this program in several ways.
# First, you can use it in the default mode to download the latest
# update and then install it to several directories.
# Second, you can use it to automate backing up files and tables when
# updating.
# Third, you can cron it and change the source of the update and use
# it to force the start of a known clean system every morning.
#
# Original Author – Brian Layman
#
# Created – 01/AUG/2006
# Last Modified – 04/JAN/2007
# Contributors: (Put your name & Initials at the top)
# Brian Layman – BL – http://www.TheCodeCave.com
#
#
# History:
# 01/AUG/2006 – BL – Created
# 21/DEC/2006 – BL – Added multiple blog arrays
# 04/JAN/2007 – BL – Added File Backup routines
#
# License – If this helps you – Great! Use it, modify it share it.
#
# Indemnity –
# Use this file at your own risk. I’m not going to deliberately hack
# your server, but others might. This is a shell script. Very bad
# things can happen. I am relatively new to *nix scripts. So
# I’ve had others review this script. But NONE of this guarantees
# things won’t go wrong or that this script is unchanged. Only
# use this script IF you’ve gotten it from TheCodeCave.com or another
# site you trust.
#
# THIS SCRIPT SHOULD BE USED AT YOUR OWN RISK. It can erase hours of
# hard work put into your site. Before using this script it is
# required that you review and understand every line and vouch for
# its safety. If you are not comfortable with this, don’t run this
# script. I have one host that I can test this on. Only you can say
# that this script will not do irreparable harm to your host if you
# use it.
#
# YOU are responsible for YOUR site. Learn how to protected it and
# understand what every line of code does before you call it.
#
# Donations – If this batch file really helps you out, feel free to
# make a donation of the cost of a cup of expresso via Paypal to
# Brian@TheCodeCave.com. A morning coffee or cheesy nachos and I
# your friend for life. And/or leave a comment on my site:
# http://www.thecodecave.com/did-that-help.
#
# *************************************************************************
# ##################################################################
# Configuration variables
# ##################################################################
# Common root is the part of your path that is shared by all of your
# WP blogs. It is probably your htdocs directory. Blank is fine if
# you want to specify the full path in the BlogDirs variable.
# Using ~ will not work.
CommonRootPrefix=”/This/is/the/path/to/your/htdocs/”
CommonBackupPrefix=”/This/is/the/path/to/your/htdocs/WPBackUps”
# CommonSQLBackupPrefix=”/This/is/the/path/to/your/htdocs/WPSQLBackUps” # Disabled in this version
# List all of your WordPress directories here
# Just number them 1-whatever
BlogDirs[1]=’site1dir’
BlogURL[1]=’www.example.com’
BlogDirs[2]=’site2/news’
BlogURL[2]=’www.site2.com/news’
BlogDirs[3]=’wordpress’
BlogURL[3]=’www.site3.com’
# PERFORMWEBSTEPS will us the wget function to perform the online upgrades.
# You might want to perform this manually. Comment out this next line if
# you want to do this step yourself
PERFORMWEBSTEPS=1 # Uncomment if you want to backup the files first
UpgradeURL[1]=’upgrade.php?step=1′
# These variable can be used to change where you get the clean copy of WordPress
# Override this variable if you wish to use this script to restore your files to
# a known version of WordPress. As part of a nightly routine, this can keep all
# of your sites running un-hacked codes.
TarBallName=’latest.tar.gz’
SourceURL=’http://wordpress.org/’
#SourcePATH=’/a/full/directory/path/’ # Uncomment if copying from a local file.
# MAKEFILEBACKUPS will back up the FILES from the folders above if it is set to 1.
# This will take time and space. If you have, for example, an uploads folder under
# one of the WP- folders above, you will make a copy of it. You may run out of
# space and that can crash your site. That’s why this step is off by default.
#MAKEFILEBACKUPS=1 # Uncomment if you want to backup the files first
# MAKESQLBACKUPS IS NOT YET RELEASED.
# MAKESQLBACKUPS enables Database backups to be made of the WP specific tables
# for each blog. It reads the database username, password and table prefix
# It is disabled by default for several reasons
# 1. Copies of a DB on a webserver is a security risk
# 2. I suspect it will not work on all systems mysqldump must be present
# 3. Your wp-config file might not allow me to read it
# 4. Your wp-config file might customized in a way I cannot predict
# 5. I’m not done testing it
#MAKESQLBACKUPS=1 # CURRENTLY THE SCRIPT WILL NOT BACKUP YOUR SQL
# ##################################################################
# Constants – Do not change these
# ##################################################################
#Error Codes
E_SUCCESS=0 # No Error Code. It worked.
E_XCD=66 # Can’t change directory?
E_XMD=67 # Can’t make directory?
E_XNOFILE=68 # No tarball file was found.
TMPPREFIX=’TCCWPUPDATE-‘
# ##################################################################
# Prepare the stage by getting the files in order.
# ##################################################################
# Seed the random number generator on bash or assign the variable on other systems
RANDOM=$$$(date +%s)
# Make Temporary directory for downloading the WordPress file
tmp=${TMPDIR-/tmp}
tmp=$tmp/$TMPPREFIX$RANDOM$RANDOM$RANDOM.$$
(umask 077 && mkdir $tmp) || {
echo “Could not create temporary directory! Exiting.” 1>&2
exit $E_XMD
}
# Show this to allow potential manual cleanup…
echo “A temp dir was created at: $tmp”
#Change to the temporary directory
cd $tmp
# Doublecheck if in right directory, before messing with downloading files.
if [ `pwd` != “$tmp” ]
then
echo “Can’t change to new temp dir. Aborting.”
exit $E_XCD
fi
# Download/Copy the tarball into the temp directory, extract it and deleted it.
if [ ! -z “$SourcePATH” ]
then
echo “Copying File: $SourcePATH$TarBallName”
cp $SourcePATH$TarBallName $tmp
if [ ! -e “$TarBallName” ]
then
rm $tmp -R # Don’t leave the temp dir out there if we don’t have to
echo “TarBall file ($SourcePATH$TarBallName) could not be copied. Aborting.”
exit $E_XNOFILE
else
echo “TarBall file ($SourceURL$TarBallName) copied.”
fi
else
echo “GETTING URL: $SourceURL$TarBallName”
wget $SourceURL$TarBallName
if [ ! -e “$TarBallName” ]
then
rm $tmp -R # Don’t leave the temp dir out there if we don’t have to
echo “TarBall file ($SourceURL$TarBallName) could not be retrieved. Aborting.”
exit $E_XNOFILE
else
echo “TarBall file ($SourceURL$TarBallName) retrieved.”
tar -zxf latest.tar.gz
rm $TarBallName
fi
fi
if [ $MAKEFILEBACKUPS ]
then
echo “Making Backups…”
BackupSuffix=-$(date +%F) # The “+%s” option to ‘date’ is GNU-specific.
if [ ! -d $CommonBackupPrefix$BackupSuffix ]; then
(umask 077 && mkdir -p $CommonBackupPrefix$BackupSuffix) || {
echo “Could not create common backup directory ($CommonBackupPrefix$BackupSuffix). Exiting.” 1>&2
rm $tmp -R # Don’t leave the temp dir out there if we don’t have to
exit $E_XMD
}
fi
BlogCount=${#BlogDirs[@]}
echo “Blog count $BlogCount”
index=1
for CurDir in “${BlogDirs[@]}”
do
echo “Processing Backups of: $CurDir”
BackupDir=$CommonBackupPrefix$BackupSuffix”/”$CurDir
echo “Making Backup to $BackupDir”
if [ ! -d $BackupDir ]; then
(umask 077 && mkdir -p $BackupDir) || {
echo “Could not create common backup directory ($BackupDir). Exiting.” 1>&2
rm $tmp -R # Don’t leave the temp dir out there if we don’t have to
exit $E_XMD
}
fi
cp -v –remove-destination $CommonRootPrefix$CurDir $BackupDir
echo “Making /wp-admin backup to $BackupDir/wp-admin”
if [ ! -d $BackupDir/wp-admin ]; then
(umask 077 && mkdir -p $BackupDir/wp-admin) || {
echo “Could not create common backup directory ($BackupDir/wp-admin). Exiting.” 1>&2
rm $tmp -R # Don’t leave the temp dir out there if we don’t have to
exit $E_XMD
}
fi
cp -R -v –remove-destination $CommonRootPrefix$CurDir/wp-admin $BackupDir/wp-admin
echo “Making /wp-content backup to $BackupDir/wp-content”
if [ ! -d $BackupDir/wp-content ]; then
(umask 077 && mkdir -p $BackupDir/wp-content) || {
echo “Could not create common backup directory ($BackupDir/wp-content). Exiting.” 1>&2
rm $tmp -R # Don’t leave the temp dir out there if we don’t have to
exit $E_XMD
}
fi
cp -R -v –remove-destination $CommonRootPrefix$CurDir/wp-content $BackupDir/wp-content
echo “Making /wp-includes Backup to $BackupDir/wp-admin”
if [ ! -d $BackupDir/wp-includes ]; then
(umask 077 && mkdir -p $BackupDir/wp-includes) || {
echo “Could not create common backup directory ($BackupDir/wp-includes). Exiting.” 1>&2
rm $tmp -R # Don’t leave the temp dir out there if we don’t have to
exit $E_XMD
}
fi
cp -R -v –remove-destination $CommonRootPrefix$CurDir/wp-includes $BackupDir/wp-includes
let “index = $index + 1”
done
fi
# ##################################################################
# Perform the full table backups before touching any files.
# ##################################################################
if [ $MAKESQLBACKUPS ]
then
echo “Making Backups…”
BackupSuffix=-$(date +%F) # The “+%s” option to ‘date’ is GNU-specific.
if [ ! -d $CommonSQLBackupPrefix$BackupSuffix ]; then
(umask 077 && mkdir -p $CommonSQLBackupPrefix$BackupSuffix) || {
echo “Could not create common SQL backup directory ($CommonBackupPrefix$BackupSuffix). Exiting.” 1>&2
rm $tmp -R # Don’t leave the temp dir out there if we don’t have to
exit $E_XMD
}
fi
BlogCount=${#BlogDirs[@]}
index=1
for CurDir in “${BlogDirs[@]}”
do
echo “Processing Backups of: $CurDir”
echo “HA! Fooled you… this is still a mockup…”
done
fi
# ##################################################################
# Iterate all of the directories and overwrite their contents.
# ##################################################################
# Loop through the BlogDirs array
for CurDir in “${BlogDirs[@]}”
do
echo “Now Updating: $CurDir”
# Go to each directory
cd $CommonRootPrefix$CurDir
# Doublecheck if in right place, before copying over hundress of files.
if [ `pwd` != “$CommonRootPrefix$CurDir” ]
then
echo “Aborting. Can’t reach one of the blog directories: $CommonRootPrefix$CurDir”
rm $tmp -R # Don’t leave the temp dir out there if we don’t have to
rm $CommonBackupPrefix$BackupSuffix -R # Don’t leave the backup dirs out there if they are not complete
exit $E_XCD
fi
# Copy all of of the files from the temp dir
cd $CommonRootPrefix$CurDir
cp -R -v –remove-destination $tmp/wordpress/* .
echo “$CurDir Update complete”
done
if [ $PERFORMWEBSTEPS ]
then
# Loop through the BlogURLS and do the update
for CurBlogURL in “${BlogURL[@]}”
do
echo “Now Updating: $CurBlogURL”
for CurUpgradeURL in “${UgradeURL[@]}”
do
wget -q $CurBlogURL$CurUpgradeURL
done
echo “$CurBlogURL Update complete”
done
fi
# ##################################################################
# Cleanup
# ##################################################################
# Once everything is done, we can remove the temp directory
rm $tmp -R
# ##################################################################
# Close
# ##################################################################
echo UPDATE COMPLETE
exit $E_SUCCESS
[/sh]
Edited file (which took a bit more than 5 seconds, must improve my typing). I also took the paranoid option of a manual backup, which I downloaded. Once I’d done that and uploaded the script, it worked immediately, no errors generated, and the site is now running 2.0.6. Nice work π
Nice script. I’ve done something similar at b5media.
Here’s a suggestion, especially for people who have TONS of sites. (I upgraded over 200 this afternoon). Make sure that the comments section of each user in /etc/passwd has the domain name.
usermod -c technosailor.com technosailor
Then, instead of having tons of arrays, you can just have a single one with all the domain names. I took this one step farther and queried MySQL first for all the domains from a single source, but barring that, add all the domains by hand to an array. They should be of the form example.com if that is the form used in /etc/passwd.
Now, loop through /etc/passwd with bash and use the
cut
command to break each line into bits using : as the separator. I use PHP as explode() works well and is simpler for me. Now you can choose the comment field and match it to the domain in the array and, using the homedir field in /etc/passwd, can easily deduce where to put your new WordPress upgrades.Works for me but it does take a little massaging. Might be better when dealing with MANY domains. Like I said, I also prefer to use PHP CLI to handle alot of my scripting.
I was building a PHP script that does the same thing. But it looks like this does what I need. Do I have to delete my WP-content folder? I never have. And can this create a back up zip? When all the files are put into the todayβs date directory, including the DB backup then it just zips it up and instead of a folder a just zip file. Thanks…
RE: Joe
> Do I have to delete my WP-content folder?
No, but I would like to know why you are asking this. WP-content is the directory that contains pretty much everything that makes your site yours. From your themes to your plugins, all of that stuff is in WP-Content. So, deleting that would reset you to a standard site (if WP recovers nicely from it). Did you see something that made you think you should?
This cannot create a zip backup at this time. It is a good idea and it floated through my mind at one point. Aparently, it floated back out again when I actually got down to writing the thing…
I will put that in a later version. Thanks for the suggestion!
I was asking because I know that it is quite important. π
This:
cp -R -v –remove-destination $CommonRootPrefix$CurDir/wp-content $BackupDir/wp-content
Does this script delete only the wp-files that need to be deleted?
About the zip, so that will be eventually in there? And what about the MySQL backup add-in? Thanks… π
Ah! I see why you asked. Good Question!
The –remove-destination works on a file by file basis with the copy command and not at the directory level.
The Man documentation says
–remove-destination remove each existing destination file before
attempting to open it (contrast with –force)
I could use force which says
-f, –force if an existing destination file cannot be
opened, remove it and try again
But it just seemed cleaner to remove the destination.
So, the only files that will be written to (or deleted) by this script are the ones that are downloaded from wp.org. This does leave some room for clutter. If a file is removed from WP, this script will not remove it from your site. Automation is a cookie cutter business, and deciding which files were deleted from the WP release is a bit beyond its safe capablities.
Yes, the Zip will be there soon as will the SQL backups and a couple more things too I hope.
Cool… I finnally got the file working 45 minutes later, it was updating my main blog and my second blog. π The Problem: an extra slash. π Thanks for the good script.
Joe: LOL Well it was supposed to save time! Just think of all the time you’ll save on 2.0.7 and 2.0.8 π
I’ll make the trailing slash status clearer in the next release!
Aaron:Thank you for the suggestion! It’s taking a bit longer for me to digest and I wanted to clear up Joe’s concern right away. I do have two minor issues with the optimization you suggest. First, people will need to edit stuff in two places. That’s gonna be harder for them to do. Second, I think that this is not gonna work for shared servers. That stuff is usually restricted isn’t it? Please correct me if I’m wrong and I’ll investigate your method further… If it speeds it up significantly and will still work for everyone, it might be worth it.
I spoke to soon, because each time the script runs no backup is created. The backup direcotry is empty. Infact I think the script can’t find the directory. But when I look at the directory using Dir it finds the directory without a problem. Any idea? π
I have 1and1 shared hosting and I tried that command and this is what I got:
USER:~ > usermod -c MY_SITE REST_OF_COMMAND
bash: ./usermod: Permission denied
Hmmm, I just ran mine again with the backup turned on and all worked smoothly. So it is creating new directories.
My variables look something like this:
CommonRootPrefix=”/kunden/homepages/00/d55555555/htdocs/”
CommonBackupPrefix=”/kunden/homepages/00/d55555555/htdocs/WPBackUps”
CommonSQLBackupPrefix=”/kunden/homepages/00/d55555555/htdocs/WPSQLBackUps”
What do yours look like?
Here’s mine:
CommonRootPrefix=”/kunden/homepages/00/d00000000/htdocs/”
CommonBackupPrefix=$CommonRootPrefix”wpbackup”
# CommonSQLBackupPrefix=”/This/is/the/path/to/your/htdocs/WPSQLBackUps” # Disabled in this version
Oh and I had another idea, all that information when the script is working goes by so fast, why not create a log within the directory that the backup is in. π Thanks…
Not sure how to do the log… I’ve been setting my putty buffer to 9999 lines. π
Your lines work fine for me.
Try this… Around line 240 change this section
[code]
cp -R -v –remove-destination $CommonRootPrefix$CurDir/wp-includes $BackupDir/wp-includes
let “index = $index + 1”
done
fi
# ##################################################################
# Perform the full table backups before touching any files.
# ##################################################################
[/code]
by adding an exit before the done like this:
[code]
cp -R -v –remove-destination $CommonRootPrefix$CurDir/wp-includes $BackupDir/wp-includes
let “index = $index + 1”
exit
done
fi
# ##################################################################
# Perform the full table backups before touching any files.
# ##################################################################
[/code]
You can more quickly see any error messages that way. I think perhaps you have some permissions issues. I thought I might run into that, but I didn’t want to arbitrarily change everyone’s permissions.
Maybe, log: I created a script it can be found at blog.fileville.net/upload/wpbackup.phps.
It works but I’m sure you could come up with something much better. But I thought I’d try any way since you’ve helped me get your script working.
Any way, I think I have solved the problem… No, it was not a extra slash this time, the script put my backup in the wrong spot the root directory, but the problem was my FTP client. It is working… Finally! Sorry for all the trouble.
Now put a check IF there is a new download version at the beginning, and one could run the whole script on a daily basis via cron.
I must say thank you! Updating 17 WordPress sites is tedious–although not that many compared to some people–but this made it a breeze.
Please see http://www.thecodecave.com/article321 for a status update and request for help.
tahnk you