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:
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:
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.