Some time ago I wrote the code below to sort my crontab file by
time (see sub compare_crons for the sorting criteria). It's
very crude, but it could work as a starting point for reading
a crontab file in memory. Once you read it in, you can make
any changes, write it to a new file, an run the crontab command
on it.
This program leaves in each element of @db an array reference
containing the 5 time fields, and a text element containing
the current line, together with any comments that came before
it. Of course, for making any modifications, this second element
would have to be split further.
eval 'exec perl -x $0 ${1+"$@"}' # -*-perl-*-
if 0;
#!perl -w
# Sort a crontab by time
# Each entry (possibly commented) is moved as a block with all the
# comment lines before it.
# Diego Zamboni, March 21, 2001. Happy Spring!
use strict;
use vars qw($curblock $tf @fields @db);
# Regex for a time field in crontab, which can be a number, sequence o
+f numbers
# or an asterisk
$tf='(?:[*]|(?:\d+(?:-\d+)?)(?:,\d+(?:-\d+)?)*)';
while (<>) {
$curblock.=$_;
if (@fields=(/^\#?($tf)\s+($tf)\s+($tf)\s+($tf)\s+($tf)\s+(.*)/)) {
push @db, [[@fields], $curblock];
$curblock="";
}
}
foreach (sort compare_crons @db) {
print "$_->[1]";
warn "-----------\n" . join(" | ", @{$_->[0]})."\n";
}
# compare by month, day, hour and minute. Ignore weekday
sub compare_crons {
my @fa=@{$a->[0]};
my @fb=@{$b->[0]};
return compare_tf($fa[3],$fb[3]) ||
compare_tf($fa[2],$fb[2]) ||
compare_tf($fa[1],$fb[1]) ||
compare_tf($fa[0],$fb[0]);
}
# Compare two cron fields. Asterisk considered as zero, otherwise
# compare by the first number
sub compare_tf {
my ($na,$nb);
$na=($_[0]=~/^(\d*)/)[0]||0;
$nb=($_[1]=~/^(\d*)/)[0]||0;
return ($na <=> $nb);
}
--ZZamboni
| [reply] [d/l] |
tune,
As always, it depends on what you need, but I could envision
a very simple script that would create a file with the
appropriate cron information in it, then executes with a
system call system ("crontab",$FILE);.
Should be pretty easy. If there is other stuff in the crontab
for that user, it gets a little tricker, but it shouldn't be
undoable.
Scott
| [reply] [d/l] |
If you wanted to get the crontab for Auser, you could do
my $user = "Auser";
my @crontab=`crontab -l $user`
Edit @crontab, and output it to a file, then execute the system call.
| [reply] [d/l] |
In addition to what's been said already a bit of background information:
You can modify the crontab-file directly, but that will not work be enough.
You have to change the timestamp of the directory in which the crontab-file resides, because that's what crond checks.
And that's what the crontab command does for you. It changes the crontab-file, either by replacing or by opening an editor for you, and it 'touches' the crontab-directory to inform crond to reread that file. | [reply] |
On Linux and Slowlaris, crontab is in /etc/crontab
Take a look at it, i would suggest using perl -i to swap out the lines that you want to change. The script will have to be run as root of course. Man crontab will give you the encoding of the time info.
Hope this helps,
-malloc
UPDATE: just read Scains's two posts, i am too used to my personal system administration to know how to do things the right way i guess :) i just couldn't think of how you could interact with crontab -e via your script. But yeah, don't use roots crontab unless absolutely necessary, thanks for the catch Scain. | [reply] |
malloc,
Why do it as root? Generally, you shouldn't be editting /etc/crontab
directly; you should instead use /usr/bin/crontab to edit it,
or to replace the existing cron information with a file, as I
suggested above. Using /usr/bin/crontab lets the script run as
the owner of the crontab information.
Scott
| [reply] |