Showing posts with label crontab. Show all posts
Showing posts with label crontab. Show all posts

Friday, October 29, 2010

hacky crontab replacement in perl

I love system admins. I have been one my self. All that power at the tips of my fingers, and a manager with a big club behind me, waiting to play wack a mole with my fingers if i mees up. Of course system admins can tell a coder that he doesn't have access to cron.... but guess what: cron was written by programmers soo.... hack yourself up a 30 min crontab system in perl and chuckle in your sleep.

Heres my hacked up mess for the day.

#!/usr/bin/env perl

use strict;
use Date::Manip;

#For the valid formats look at 
#http://search.cpan.org/~muir/Time-modules-2003.0211/lib/Time/ParseDate.pm

my $period = 10;
my @tasks = (
             { time => "09:00:00", label => "morning", cmd  => "echo 'good morning'"},
             { time => "01:34:00", label => "Hi", cmd  => "echo 'good morning'"},
             { step => "+ 1 minutes", label => "5 mins", cmd  => "echo '5 mins'"},
             { step => "+ 10 seconds", label => "10 seconsd", cmd  => "echo '5 mins'"}
             
             );

sub string2date
{
    my ($str) = @_;
    return int(UnixDate($str, "%s")); 
}

sub secsDiff
{
    my ($str) = @_;
    return string2date($str) - string2date("now");
}

sub update_firetime
{
    my ($task, $now) = @_;
    my $new = $now;
    if(defined $task->{time})
    {
        $new = string2date($task->{time});
        $new += secsDiff("+ 1 day") if $new < $now;
    }
    elsif(defined $task->{step})
    {
        $new  = $now;
        $new += secsDiff($task->{step}) while $new <= $now;
    }
    $task->{fire_time} = $new;

}

sub boot
{
    my $now = string2date("now");    
    update_firetime($_, $now)
        foreach (@tasks);
}

sub execute
{
    my ($task) = @_;

    my $pid = fork();
    if((defined $pid) && ($pid == 0)) 
    {
        if(defined $task->{xterm} && $task->{xterm} == 1)
        {
            #boot and leave an xt
            my $label   = $task->{label};
            my $cmd     = $task->{cmd};
            my $sys_cmd = "xterm -xrm 'XTerm*foreground: red3' -xrm 'XTerm*background: black' -title 'CRONTAB:$label' -e sh -c \"$cmd; ksh\" &";
            
            system($sys_cmd);
        }
        else
        {
            #just execute it..
            system($task->{cmd});
        }
        exit(0);
    }
}

sub cron_core
{
    while(1)
    {
        my $now = string2date("now");
        foreach my $task (@tasks)
        {
            if($now > $task->{fire_time})
            {
                print "fire! $task->{label}\n";
                execute($task);
                update_firetime($task, $now) 
            }
        }
        #cron loop an launch
        
        print("sleeping.....\n");
        sleep($period);
    }
}

print "Operating with an accuracy of +/-$period seconds\n";

boot();
cron_core();