0

I'm trying to setup a relatively short shell script called backup_extract.sh which will essentially unzip a zip file, drop a database, create a database of the same name, then import an sql file that was created from the zip file.

This zip file is created on a separate server, then transferred to this server every day - it's a simple database backup of a wordpress website & this script is intended to restore that database on the new server to serve as a 1:1 clone of the other website for backup purposes.

The problem I'm having is when I just bash run the script it works fine, but when I let cron take over nothing seems to happen.

Code looks a bit like this (obviously omitting mysql user & password, as well as full urls but I assure you i am using the exact path to the files as if they were from the root)

cd /var/www/html/backups/database
mkdir /var/www/html/backups/database/$(date +%Y%m%d)
unzip /var/www/html/backups/database/*.zip -d /var/www/html/backups/database/$(date +%Y%m%d)
mv /var/www/html/backups/database/*.zip /var/ww/html/backups/database/$(date +%Y%m%d)
cd /var/www/html/backups/database/$(date +%Y%m%d)/dup-installer
mv /var/www/html/backups/database/$(date +%Y%m%d)/dup-installer/*.sql /var/www/html/backups/database/$(date +%Y%m%d)/dup-installer/database_$(date +%Y%m%d).sql
mysql -u USERNAME -p'PASSWORD' database -e \ 'DROP DATABASE database';
mysql -u USERNAME -p'PASSWORD' -e \ 'CREATE DATABASE database';
mysql -u USERNAME -p'PASSWORD' database < /var/www/html/backups/database/$(date +%Y%m%d)/dup-installer/database_$(date +%Y%m%d).sql
echo "Backup completed" >> /var/www/html/backups/database/$(date +%Y%m%d)/backup-status.txt

Now this is my first time writing a script like this and I'm sure I'm doing some things wrong. But let me explain a few things about what this script is doing.

First I have no idea if the cd commands do anything at all when the crontab is involved, but they're there just in case. if i don't need them great.

2nd a directory is created using the current date

3rd a zip file is unzipped into the folder we just created - this is where it gets complicated. every day a new zip file will be moved to this folder, however the name is procedurally generated by a different server & there's no way to predict EXACTLY what the zip file's name will be so I need a way to unzip any zip file that exists in this folder - it will be moved once it is unzipped so there's no worry about unzipping several zip files at once.

4th the zip file is moved to the folder we created on line 2

5th we cd into a folder that was unzipped from the zip file

6th we rename any sql file in here (there will only ever be 1) to a name that is more predictable (same issue with this as there was with the zip file, the sql filename is unpredictable & therefore hard to lock down so I used wildcard to target any sql files in that folder.

7th we login to MySQL & drop the database

8th we login to MySQL & re-create the database with the same name as the one we just deleted

9th we login to MySQL & Import the sql file we renamed earlier

10th we create an arbitrary text file that just says backup completed

I've tested the shell script on its own using bash -x several times & it seems to be working fine. there are a few issues like it doesn't actually seem to care what folder the .zip file is in & wants to unzip EVERY zip file on the server which isn't good, but the core issue is that crontab isn't working. my crontab line is this:

00 00 * * * /var/www/html/(actual filepath)/backups/backup_extract.sh

I've been changing the times while testing, but generally that's what it looks.

When I check/var/log/cron it acts like it has run the script, but in actuality it has done nothing.

I've even tried creating a simple crontest.sh file that just creates a crontest.txt file & tested that both using bash & using cron - bash works fine but cron does not.

  • For anyone who may be curious, this is on an amazon AWS EC2 Linux Server. I've already checked the crond service to make sure it is running & it is (of course if it weren't I wouldn't even be getting any updates to my cron log but just trying to reduce the potential points of failure) – Trenton Moore Apr 3 at 20:27
  • you should redirect stderr and stdout to a file in your cron and see the output to check for any error or unconsistent ouput 00 00 * * * /var/www/html/(actual filepath)/backups/backup_extract.sh 2>&1 >> /path/to/log/file.txt – Zeitounator Apr 3 at 21:12
  • 1
    This doesn’t sound like a cron problem but an issue with your script. – DarkHeart Apr 3 at 21:37
  • Well I've run the script using bash like I said & it works fine. I've even tried running just a basic script echoing a string to a text file. tried using both cron & bash - again the bash works & cron doesn't. And the whole script is above, if there's something wrong with it by all means feel free to point it out. Like I said it's my first time writing anything like this so there's bound to be mistakes. – Trenton Moore Apr 3 at 21:41
1

How did you create your crontab file? If you used crontab -e as a non-root user then the process will not have sufficient privileges to modify the /var/www tree.

If you created it as root then it's likely your $PATH is not set so the invocation of mysql will fail.

If you edited the /etc/crontab file you are missing a username field.

You also have a typo in line 4 where the target is stated as /var/ww/...

  • I used crontab -e as a root user, I have not changed the path from the default so if the default is not set, how should I set it? and what should I set it to so that the invocation of mysql will NOT fail? Thanks for pointing out that typo. – Trenton Moore Apr 3 at 21:09
  • Just use the full path in your crontab to the mysql binary. – anonymouse Apr 3 at 21:12
  • As I said in my question, I've never really done this before, this is my first time doing anything even remotely like this & I don't have much experience with linux in general. Most of what I've done has been gathered from bits & pieces of information around the net so I have no idea what I'm doing honestly. with that being said, where would I potentially find the mysql binary? – Trenton Moore Apr 3 at 21:18
  • type which mysql at the command line and then replace your mysql with the output of that command. – anonymouse Apr 3 at 21:27
  • I tried that but no luck. cron log shows that its running the command, but im not seeing any of my folders created or zip files unzipped, not even the text file at the end. – Trenton Moore Apr 3 at 21:37
0

My solution for this may not be the same for everyone but basically crontab -e didn't work AT ALL. I ended up having to edit /etc/crontab.

Set the PATH variable to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin, the SHELL to /bin/bash, then added my cron jobs in that file. Now the cron job is running correctly.

I'm not sure why crontab -e didn't work, I'm sure someone with more experience could give some possible reasons but I'm completely clueless.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.