Backing up Cron and Unix Command Lines

Today I have been mostly messing with UNIX command lines. This post details the work of part of the day.

I have a cron job set up which automatically backs up the crontab. Crontab is a thing which executes schedules commands.

WinXP has a scheduler, as does OSX. In linux you can get to the file by typing 'crontab -e' (you will probably be in vi, so you may want to look up how to use vi!)

This is the line in crontab:

15 19 * * * 
crontab -l 
> ~/backup.cron/cronbackup.$(date +\%m).$(date +\%d)

This, as with other commands, is actually on one line, I have split it for clarity. That says, once a day put a copy of the cron into a file labelled cronbackup.08.24 (for today).

There will be lots of files created, but I am not that bothered as each one is small. However, I need to delete the files after some time. I need this litterbug to have an accompanying litterpicker

The brute force method is to schedule a cron job to delete the files from X months earlier, for example:

15 19 1 9 * rm ~/backup.cron/cronbackup.06*

Fairly easy to do, but it would need 12 lines in the cron, and editing it to maintain a different duration of log would be a pain.

I decided to try and be clever. Surely, thought I, it would be possible to get the machine to automagically subtract X months from the date?

The first thing was to try and do some sums on the date.

d=$(date +\%m); expr $d / 10 ; 
expr \( $d - 1 \) % 10 + 1

This outputs something like:

0
8

for August.

This one may not look much, but it is necessary in order to keep the leading zero. The next step is to bolt things back together:

d=$(date +\%m); 
a=$(expr $d / 10) ; 
b=$(expr \( $d - 1 \) % 10 + 1) ; 
echo $a$b

For August this outputs:

08

as required.

The next step is to start manipulating the date.

c=2 ; 
d=$(date +\%m); d=$(expr \( $d - $c \)) ; 
a=$(expr $d / 10) ;
b=$(expr \( $d - 1 \) % 10 + 1) ; 
echo $a$b

This adds two things, first the value of the correction. In this case the correction is 2, then the value of d is changed by 2. So, for august, we get 6

Unfortunately there is a bug, as demonstrated by changing c to 9. The result is 0-1, a correct result, but not desired. Ideally the result should be 11.

One solution is to put in an if statement which says that if d is less than 1, add 12. Unfortunately I have yet to get this to work on a command line.

I came up with this. The inequality yields a 1 if the result is out of range, zero if it is okay as is. This is multiplied by 12, and then added on to the number we first thought of:

c=$(expr \( $d \< 1 \) \* 12) ; 
d=$(expr \( $d + $c \));

and the expression becomes:

c=2 ; 
d=$(date +\%m); d=$(expr \( $d - $c \)); 
c=$(expr \( $d \< 1 \) \* 12) ; 
d=$(expr \( $d + $c \)); a=$(expr $d / 10) ; 
b=$(expr \( $d - 1 \) % 10 + 1) ; 
echo $a$b

Adding the timing info for crontab, my final expression is:

20 20 1 * * c=2 ; 
d=$(date +\%m); 
d=$(expr \( $d - $c \)); 
c=$(expr \( $d \< 1 \) \* 12) ; 
d=$(expr \( $d + $c \)); 
a=$(expr $d / 10) ; 
b=$(expr \( $d - 1 \) % 10 + 1) ; 
rm ~/backup.cron/cronbackup.$a$b* > /dev/null 2>&1

The final dev/null thing suppresses errors for the first few months before the backups exist, or if I delete them manually.

This solution is a bit complex, and it may have I bug which I have not seen (if it does, please comment), but I can change the backup retention time with a single change - the initial value of c.