This is a post not directly related to Android, but to my NAS where I am storing all my personal files. I bought the Synology DS212+ some month ago and I am very happy with it. Having two 2TB hard disks build in, another external harddisk is connected via USB 3.0 for backup resons. This Harddisk I am switching on and off manually from time to time and when it is switched on, a cron job should back up all the files of the DS using rsnapshot to my backup disk.
On a first glance this should not be such a big problem, but digging into it there are some problems to be solved:
- starting the backup once via cron, the external harddisk might be switched off and no backup will be done :(
- starting the backup regularly via cron might lead to multiple backups for a single day :(
Unfortunately Synology is not providing anacron which provides the possibility to specify such "run once a period" tasks. I digged a bit around, but I couldn't find a simple suitable solution for my needs, so I wrote a small shell script which does the trick:
#!/bin/ash
#
# shell script to run a job once a period
# it takes three parameters:
# - name of the runfile
# - period definition ("1 day", "2 days", ..., "1 week", "2 weeks", ... "1 month", etc.)
# - program to be executed (i.e. backup-program / script)
#
#
# some helper functions
#
date2stamp () {
date --utc --date "$1" +%s
}
stamp2date (){
date --utc --date "1970-01-01 $1 sec" "+%Y-%m-%d %T"
}
dateDiff (){
case $1 in
-s) sec=1; shift;;
-m) sec=60; shift;;
-h) sec=3600; shift;;
-d) sec=86400; shift;;
*) sec=86400;;
esac
dte1=$(date2stamp $1)
dte2=$(date2stamp $2)
diffSec=$((dte2-dte1))
echo $((diffSec/sec))
}
###########################################################
#
#main program
###########################################################
EXECUTE="0"
RUNFILE=/var/run/$1
LOCKFILE=/var/run/"$1".lock
if [ -f $LOCKFILE ]
then
echo "other process running -> exiting" >> /var/log/runOnce.log
exit 2
fi
touch $LOCKFILE
#
# check whether runfile exists
#
NOW=`date -d 'now' --iso-8601`
if [ -f $RUNFILE ]
then
NEXTRUN=`cat $RUNFILE`
# check wether next run date is in the past
if [ `dateDiff -d "$NEXTRUN" "$NOW"` -ge 0 ]
then
EXECUTE="1"
fi
else
# did not run yet -> run forced
EXECUTE="1"
NEXTRUN=`date -d 'now' --iso-8601`
fi
if [ "$EXECUTE" == "1" ]
then
# execute (i.e. backup)
$3
STATUS_CODE=$?
if [ $STATUS_CODE -eq 0 ]
then
# set next execution date
while [ `dateDiff -d "$NEXTRUN" "$NOW"` -ge 0 ]
do
# add period
NEXTRUN=`date -d "$NEXTRUN + $2" --iso-8601`
done
# set next execution date
echo $NEXTRUN > $RUNFILE
fi
fi
rm $LOCKFILE
exit 0
This script in combination with some entries in my crontab did the trick. ;)
20 18-23 * * * root /root/runOnce.sh backupWeekly "1 week" /root/runWeeklyBackup.sh
40 18-23 * * * root /root/runOnce.sh backupMonthly "1 month" /root/runMonthlyBackup.sh