Score:0

script backups sqlite database, when ran as a cron the db and names are mangled

in flag

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.

Egidijus avatar
nz flag
For things like backups, I recommend use absolute paths for binaries, to make sure you are using expected version. +1 you should use bash, or, create a cronjob to print env vars to debug what your cron runs things with, vs what you have.
Score:4
gu flag

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.

Ginnungagap avatar
gu flag
I've had to type this on my phone so please feel free to fix any mistakes via the edit button and accept my apologies in advance for any I might have made
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.