script backups sqlite database, when ran as a cron the db and names are mangled
I have a crontab:
* * * * * /home/ipa/web/backup.sh > /dev/null 2>&1
(No it doesn't run every minute just testing here)
The backup.sh has this:
#!/usr/bin/env sh
sqlite3 /home/ipa/web/ipa_django/mysite/db.sqlite3 ".backup 'backup_file.sqlite3'"
src="/home/ipa/web/backup_file.sqlite3"
let seconds=$(date +%H)*3600+$(date +%M)*60+$(date +%S)
echo $seconds
filename="db.sqlite3"
echo $filename.$seconds
dest="/home/ipa/web/db_backups/"$filename.$seconds
cp $src $dest
cd /home/ipa/web/db_backups
tar -cvzf ipadbbackup.tar.gz $filename.$seconds
cd /home/ipa/web/
cp /home/ipa/web/db_backups/ipadbbackup.tar.gz ipadbbackup.tar.gz
rm /home/ipa/web/db_backups/$filename.$seconds
rm /home/ipa/web/db_backups/ipadbbackup.tar.gz
#rm "$srcfile"
/usr/bin/bash start-app.sh;
echo "Running email backup"
python2.7 backup_via_email.py
rm ipadbbackup.tar.gz
The idea is I copy the database to a scratch area, zip it up copy it to where another .py file can find it and email it off as a backup.
The problem is:
If I run this script from where it lives: /home/ipa/web/
with a ./backup.sh
It works great, I get the file in my email works great: db.sqlite3.77627
or what not... the problem is when it runs as a cron the file is not complete and the file name is:
db.sqlite3.
I cannot figure out what about it running as a cron is making it fail essentially? The file in the tar is also 2.1k smaller? So not sure what is going on... not even sure where to look.
Solution 1:
Most likely, you're not actually running ./backup.sh
when running it manually but rather bash ./backup.sh
.
The only POSIX compliant way to compute a value through the shell is with $(( expr ))
.
In general, unless you have very good reason, scripts should use bash since most people don't know the difference between sh and bash and will just write broken scripts.
#!/usr/bin/env bash
set -e
set -u
declare -r db_src="/home/ipa/web/ipa_django/mysite/db.sqlite3"
declare -r db_bak="/home/ipa/web/backup_file.sqlite3"
declare -r db_dst="/home/ipa/web/db_backups/db.sqlite3.$[ EPOCHSECONDS % 86400 ]"
sqlite3 "${db_src}" ".backup 'backup_file.sqlite3'"
cp "${db_bak}" "${db_dst}"
cd "$( dirname "${db_dst}" )"
tar -czf "/home/ipa/web/ipadbbackup.tar.gz" "$( basename "${db_dst}" )"
rm "${db_dst}"
echo "Running email backup"
cd "/home/ipa/web"
python2.7 backup_via_email.py
rm ipadbbackup.tar.gz
Always make sure to log your cron output when attempting to debug, I'm guessing you'd have seen a command not found: let
somewhere.