Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash script to backup server upload folders

Tags:

regex

bash

ssh

sed

I have a CentOS server running WHM/cPanel sites, and a lot of these sites run WordPress. I would like to do an automated backup that zips and moves any account containing an 'uploads' folder into a backup directory. I know there are other solutions, but most want you to backup the entire WordPress site, I only need to backup the uploads however.

I'm not very good with .sh scripts and have spent a lot of time already trying to figure this out, but I can't seem to find any examples similar enough for me to be successful. The main problem I have is naming the zip after the account.

Location of most upload folders (user1 being the account that changes):

/home/user1/public_html/wp-content/uploads /home/user2/public_html/wp-content/uploads /home/user3/public_html/wp-content/uploads

Script example:

find /home/ -type d -name uploads -exec sh -c 'zip -r /backup/uploads/alluploads.zip `dirname $0`/`basename $0`' {} \;

The problem with this approach is that it all writes to one single zip file. How can I alter this to save each users uploads to there own user1-uploads.zip file?

I've played around with exec and sed but I can't seem to figure it out. This is the best I got - just trying to get it to echo the name - but it's not right. Sorry, I'm terrible with regex:

find /home/ -type d -name uploads -exec sh -c 'string=`dirname $0` echo $string | sed `/\/home\/\(.*\)\/new\/wp-content\/uploads/`'{} \;

Would appreciate any help or directions on how to fix this. Thanks!

like image 975
sucramv Avatar asked May 29 '26 01:05

sucramv


2 Answers

You can use Bash's globbing with * to expand all the different user directories.

for uploads in /home/*/public_html/wp-content/uploads; do
    IFS=/ read -r _ _ user _ <<<"$uploads"
    zip -r /backup/uploads/${user}.zip "$uploads"
done
like image 79
John B Avatar answered May 31 '26 14:05

John B


A couple of solutions come to mind, you could loop through the user directories:

cd /home
for udir in *; do
   find /home/$udir -type d -name uploads -exec sh -c 'zip -r /backup/uploads/'"$udir"'-uploads.zip `dirname $0`/`basename $0`' {} \;
done

or use cut to get the second element of the path:

find /home/ -type d -name uploads -exec sh -c 'zip -r /backup/uploads/`echo "$0" | cut -d/ -f 2`-uploads.zip `dirname $0`/`basename $0`' {} \;

Although both of these would run into issues if the user has more than 1 directory anywhere under their home that is named uploads

You might use tr to simply replace the path separator with another character so you end up with a separate zip for each uploads directory:

find /home/ -type d -name uploads -exec sh -c 'zip -r /backup/uploads/`echo $0 | tr "/" "-"`.zip `dirname $0`/`basename $0`' {} \; 

so you would end up wil files named /backup/uploads/home-user-wp-content-uploads.zip and /backup/uploads/home-user-wip-uploads.zip instead of one zip overwriting the other

like image 41
Joe Avatar answered May 31 '26 14:05

Joe