Solved

Cron emulator/ faking cron

Posted on 2002-07-05
25
652 Views
Last Modified: 2010-05-18
Does anyone know a free script that will emulation the Unix cron utility.

I am not allowed to use cron to automate action every day have to be done automatically.

I would like it to use on a unix machine.

Can I use the sleep function?

Can someone help me to a script?
0
Comment
Question by:mmcw
  • 12
  • 8
  • 2
  • +2
25 Comments
 
LVL 84

Expert Comment

by:ozo
ID: 7132864
use Schedule::Cron;
0
 

Author Comment

by:mmcw
ID: 7132975
How to use that and where to find it?
0
 
LVL 84

Expert Comment

by:ozo
ID: 7133022
0
ScreenConnect 6.0 Free Trial

Discover new time-saving features in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

 

Author Comment

by:mmcw
ID: 7133336
Thank you for your answer.
But I can not use it because I am not allowed to install modules my self!

Isn't there way to use foreample the sleep command?
0
 

Author Comment

by:mmcw
ID: 7133349
Ozo:
Is it save to use something like this
(found at: http://www.experts-exchange.com/questions/Q_20091375.html)

#############################################
#!/usr/bin/perl -w
print "Content-type: text/html\n\n";

use Socket;

while(1){
$content = get("http://www.my.url/file.csv") or die $!;
open (STOCK, "> /path/to/my/dir/stock.csv") or die "I don't wanna! \n";
print STOCK $content;
close (STOCK);
sleep(3*60*60);
}

sub get {
$url = shift;
$url =~ s|http://([^/:]+)(:(\d+))?||;
$remote = $1;
$port = $3 || 80;
$url or $url = "/";
$iaddr = inet_aton($remote) || return undef;
$paddr = sockaddr_in($port, $iaddr);
$proto = getprotobyname('tcp');
socket(SOCK, PF_INET, SOCK_STREAM, $proto)  || return undef;
connect(SOCK, $paddr) || return undef;
$old = select SOCK; $|++; select $old;
print SOCK "GET $url HTTP/1.1\r\nHost: $remote\r\n\r\n";
while (<SOCK>) {
   /Content-Length: (\d+)/ and $bytes = $1;
   if ($_ eq "\r\n") {
      <SOCK>;
      last;
   }
}
$bytes or return undef;
read SOCK ,$contents, $bytes;
close SOCK;
return $contents;
}
########################################

A sleep routine what will check a file for the word "off" to see if it has to continu.

Can this be used?
What about the processor time?
0
 
LVL 84

Expert Comment

by:ozo
ID: 7133367
Looks like it should work on a unix system,
otherwise, you might have to use "\015\012" for "\r\n"
0
 
LVL 84

Expert Comment

by:ozo
ID: 7133369
You should probably also close SOCK even when you return undef
0
 

Author Comment

by:mmcw
ID: 7133383
Will I get problems with my provider about cpu and memory time running this script?
0
 
LVL 84

Expert Comment

by:ozo
ID: 7133392
I don't know your providers policy about cpu and memory time, and I don't know how big http://www.my.url/file.csv is,
but "get"ing it once every 3 hours doesn't seem unreasonable to me.
0
 

Author Comment

by:mmcw
ID: 7133403
When the script is in sleep it should be no problem for the provider? The script will then not use memory or cpu time?
0
 
LVL 84

Accepted Solution

by:
ozo earned 200 total points
ID: 7133412
The script will continue to use memory, although it will probably get swapped out before long.
It will not use cpu time while sleeping
0
 

Author Comment

by:mmcw
ID: 7133434
Or do you have a better idea without using extra (not standard) modules?
0
 

Author Comment

by:mmcw
ID: 7133439
How to stop the sleep process?
Can I use the option (very creative) used at:
http://www.experts-exchange.com/questions/Q_20091375.html
0
 
LVL 3

Expert Comment

by:DVB
ID: 7134622
(Wondering why he can't install modules in his home directory)
Use a signal to stop the sleep process.
$SIG{TERM}=&my_signal_handler();

sub my_signal_handler()
{
     (flush anything you want)
     close (all open files/handles);
     exit 0;
}

This will properly shutdown your process.

0
 

Author Comment

by:mmcw
ID: 7134651
"(Wondering why he can't install modules in his home directory)"

How to install the module Schedule::Cron; in my home directory? I do not have root rights!

"Use a signal to stop the sleep process.
$SIG{TERM}=&my_signal_handler();

sub my_signal_handler()
{
    (flush anything you want)
    close (all open files/handles);
    exit 0;
}"

Could you help me implementing it into the code I gave in an earlier comment!

This will properly shutdown your process.
0
 
LVL 3

Expert Comment

by:DVB
ID: 7140728
If you run perl -MCPAN -eshell, it will ask you lots of questions about where you want stuff installed.
Or you could just pass a parameter to the Makefile.PL telling it that you want installations to occur in your home directory. you should have full write permission in your home directory, that doesn't need root access.

And that sample code works as is.
You introduce a custom handler for SIGTERM with
$SIG{TERM}=&my_sig_handler;

#The signal handler
sub my_sig_handler()
{
     #This assumes stock was open.
     fflush(STOCK);
     close (STOCK);
     exit 0;
}

Hopefully, this gives you an idea of how to install a signal handler. I really really recommend getting the camel book, and the cookbook.
0
 
LVL 10

Expert Comment

by:oleber
ID: 7153892
After having a problem like yours. My provider didn't let me use a cron and what I have to do didn't take long (just send some mail or preprocesse some pages that are slower).

I set the code necessary in a script that is usualy seen. That way the necessary code run and do the work. Like the code run less than 1% of the time that the scripts runs I dont have probleme whith my clients.

For resolving the problem of instaling modules, you can have modules isntalled in a directory that you control and set the code 'use lib("..\\modules");', for me works until now.

0
 

Expert Comment

by:weversbv
ID: 7154073
After having a problem like yours. My provider didn't let me use a cron and what I have to do didn't take long (just send some mail or preprocesse some pages that are slower).

"I set the code necessary in a script that is usualy seen. That way the necessary code run and do the work. Like the code run less than 1% of the time that the scripts runs I dont have probleme whith my clients."

What script so you use???

"For resolving the problem of instaling modules, you can have modules isntalled in a directory that you control and set the code 'use lib("..\\modules");', for me works until now."

How to do that???
0
 

Author Comment

by:mmcw
ID: 7154089
Weversbv is asking the same I want to know?

"I set the code necessary in a script that is usualy seen. That way the necessary code run and do the work. Like the code run less than 1% of the time that the scripts runs I dont have probleme whith my clients."

What script so you use???

"For resolving the problem of instaling modules, you can have modules isntalled in a directory that you control and set the code 'use lib("..\\modules");', for me works until now."

How to setup the Schedule::Cron module local???
0
 
LVL 10

Expert Comment

by:oleber
ID: 7154169
What script so you use???
The banner page of the site. Can be slow, who cares. See http://www.oleber.com .

How to setup the Schedule::Cron module local???
I didn't use the Schedule::Cron, I did my code directly in the script. I use other modules like HTML::Modules, Net::SMTP, ... In this cases you just have to uncompact the content of the zip file and copy the files to the correct places in modules directory.

insted of using the crons, you can sink something like

if (time() % 1000 == 0)
{
  # do 1º work
}
if (time() % 1001 == 0)
{
  # do 2º work
}
if (time() % 1002 == 0)
{
  # do 3º work
}

its just one idea that can work.
0
 

Author Comment

by:mmcw
ID: 7273915
OZO:

I did now install this module but do not know how to continu.

This is what I want:

I want to run every day at 08.00 the perl script: www.test.com/cgi-bin/test.pl?action=test

How to do that with the schedule::cron module.

I did read the documentation but I stiil do not kown what to do?

Could you tell me what line do I have to add to my script?
0
 

Author Comment

by:mmcw
ID: 7289137
I have found on the internet the following code. I have edited it a bit to make it work like cron. It will check every minute the crontab file to see if something has to be executed. To stop it I have added the part where a file stop.txt will be checked. If the value in the file is off the process will stop.

This is my problem. When I start this script from my browser it seem to load for ever. The script runs in the background. When you push the stop button of the browser the cron.pl script keeps running. That is what I want, but is it possible to return only an message to the browsers screen that the perl script is started. Not the endless loading of the page!

#!/usr/local/bin/perl
#########################################################################
#                                                                                                            #
# subroutine cron -- perl implementation of cron                                    #
#                                                                                                            #
#########################################################################
# $silent to 1, means no output to screen.
# $log to 1, means keep a log file of activity.
# $logmsg to 1, means keep a log file of the messages.

$silent = 0;
$log = 1;
$logmsg = 1; # assign this only in emergency
$stopfile = "/home/cgi-bin/Shop/Div/stop.txt";
$logfile = "/home/cgi-bin/Shop/Log/cronlog.txt";
$errfile = "/home/cgi-bin/Shop/Log/errorlog.txt";

# Start cron
start_cron();

#########################################################################
#                                                                                                            #
# main program                                                                                          #
#                                                                                                            #
#########################################################################

sub start_cron {
      
      print "Content-type: text/html\n\n";

      # return and let child do the work
      if (fork) {
               exit;
      }
      
      unless ($silent) {
            # Print to screen
            print "Crontab: scheduled tasks [$$] started.<br>\n";
      }

      # check file for on-off switch
      CSF(1);
      
      if (defined $ARGV[0]) {
            LOG("ACT", "using $ARGV[0] as crontab file\n");
            $crontab = $ARGV[0];
      }
      else {
            LOG("ACT", "using default file crontab");
            $crontab = "/home/cgi-bin/Shop/Div/crontab";
      }

      while (1) {

            # check file for on-off switch
            CSF();

          # Sleep till next minute
            my $icur_secs = time();
          my $icur_mins = int ( $icur_secs / 60 );
          my $next_mins = $icur_mins + 1;
          my $next_secs = $next_mins * 60;
          my $sleep_secs = $next_secs - $icur_secs;
          sleep( $sleep_secs );

            # mon = 0..11 and wday = 0..6
            my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
            $mon++; # to get it to agree with the cron syntax
            $year = $year + 1900;

            # check crontab file
            open(F, "$crontab") or
              LOG("ERR", "$!: Can't open crontab file: $crontab") or
                  die "Can't open crontab; file $crontab: $!\n";
                  
                  $line = 0;

                  while (<F>) {
                        $line++;

                        if (/^$/) {
                              LOG("MSG", "blank line $line");
                              next;
                        }

                        if (/^#/) {
                              LOG("MSG", "comment on line $line");
                              next;
                        }

                        ($tmin, $thour, $tmday, $tmon, $twday, $tcommand) = split(/ +/, $_, 6);
                        # pull out commands with spaces
                        if (/\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+(.+)$/) {
                              $tcommand = $1;
                        }

                        LOG("MSG", "it is now " . sprintf "%02d:%02d:%02d on %02d/%02d/%02d wday=%02d", $hour, $min, $sec, $mon, $mday, $year, $wday);
                        LOG("MSG", "should we do $thour:$tmin on $tmon/$tmday/--, wday=$twday?");

                        $do_it = 0; # assume don't do it until proven otherwise

                        # do it -- this month?
                        if ( ($tmon eq "*") || ($mon == $tmon) || &in_csl($mon, $tmon, '1', '12')) {
                              $do_it = 1;
                              LOG("MSG", "the month is valid");
                        }
                        else {
                              $do_it = 0;
                              LOG("MSG", "cron: the month is invalid");
                        }

                        # do it -- this day of the month?
                        if ( $do_it && ( ($tmday eq "*") || ($mday == $tmday) || &in_csl($mday, $tmday, '1', '31')) ) {
                              $do_it = 1;
                              LOG("MSG", "the day of month is valid");
                        }
                        else {
                              $do_it = 0;
                              LOG("MSG", "the day of month is invalid");
                        }

                        # do it -- this day of the week?
                        if ( $do_it && ( ($twday eq "*") || ($wday == $twday) || &in_csl($wday, $twday, '0', '6')) ) {
                              $do_it = 1;
                              LOG("MSG", "the day of week is valid");
                        }
                        else {
                              $do_it = 0;
                              LOG("MSG", "the day of week is invalid");
                        }

                        # do it -- this hour?
                        if ( $do_it && ( ($thour eq "*") || ($hour == $thour)|| &in_csl($hour, $thour, '0', '23') ) ) {
                              $do_it = 1;
                              LOG("MSG", "the hour is valid");
                        }
                        else {
                              $do_it = 0;
                              LOG("MSG", "the hour is invalid");
                        }

                        # do it -- this minute?
                        if ( $do_it && ( ($tmin eq "*") || ($min == $tmin) || &in_csl($min, $tmin, '0', '59') ) ) {
                              $do_it = 1;
                              LOG("MSG", "the min is valid");
                        }
                        else {
                              $do_it = 0;
                              LOG("MSG", "the minute is invalid");
                        }

                        # executing command
                        if ($do_it) {
                              chomp $tcommand;
      
                              if ($tcommand =~ /^http/) {
                                    LOG("ACT", "executing command <$tcommand> using LWP::simple");

                                    use LWP::Simple;
                                    getprint("$tcommand");
                              }
                              else {
                                    LOG("ACT", "executing command <$tcommand>");

                                    system ("$tcommand");
                              }
                        }
                  }

            close(F);
            LOG("MSG", "***-----***");
      }

      exit;
}

#########################################################################
#                                                                                                            #
# in_csl searches for an element in a comma separated list                        #
#                                                                                                            #
#########################################################################

sub in_csl {
      my ($what, $csl, $start, $end) = @_;
      
      # Local variables
      my (@a, @b);
      my ($i, $x);

      LOG("MSG", "Processing CSL");
      @a = split(/,/, $csl);
      @b = ();
      map {
            if (/^(\d+)\/(\d+)$/) {
                  if ($2 > 0 && $1 >= $start && $1 <= $end) {
                        for ($i = $1; $i <= $end; $i += $2) {
                              push(@b, $i);
                        }
                  }
            }
            elsif (/^\*\/(\d+)$/) {
                  if ($1 > 0) {
                        for ($i = $start; $i <= $end; $i += $1) {
                              push(@b, $i);
                        }
                  }
            }
            elsif (/^(\d+)-(\d+)\/(\d+)$/) {
                  if ($3 > 0) {
                        if ($1 <= $2) {
                              for ($i = $1; $i <= $2; $i += $3) {
                                    push(@b, $i);
                              }
                        }
                        else {
                              for ($i = $1; $i <= $2 + $end + (1 - $start); $i += $3) {
                                    if ($i <= $end) {
                            push(@b, $i);
                                    }
                                    else {
                                          push(@b, $i - $end - (1 - $start));
                                    }
                              }
                        }
                  }
            }
            elsif (/^(\d+)-(\d+)$/) {
                  if ($1 <= $2) {
                        for ($i = $1; $i <= $2; $i++) {
                              push(@b, $i);
                        }
                  }
                  else {
                        for ($i = $1; $i <= $2 + $end + (1 - $start); $i++) {
                              if ($i <= $end) {
                                    push(@b, $i);
                              }
                              else {
                                    push(@b, $i - $end - (1 - $start));
                              }
                        }
                  }
            }
            else {
                  push(@b, $_);
            }
      } @a;
   
      for $x (@b) {
        LOG("MSG", "is $what equal to item $x?");
        if ($what eq $x) {
            return 1;
        }
    }
   
      return 0;
}

#########################################################################
#                                                                                                            #
# Check for stopfile and/ or stop process                                                #
#                                                                                                            #
#########################################################################

sub CSF {
      
      my $sfc = shift;
      
      # check file for on-off switch
      open (DAT, "$stopfile") or
             LOG("ERR", "$!: Can't open stopfile file: $stopfile") or
            die "Can't open stopfile; file $stopfile: $!\n";

            my $state = <DAT>;
            if ($state =~ /off/i) {
                  if ($sfc) {
                        unless ($silent) {
                              # Print to screen
                              print "Crontab: scheduled tasks disabled.<br>\n";
                              print "Crontab: stop file = off.<br>\n";
                        }
                        
                        # Print to error log file
                        LOG("ERR", "tried to start disabled scheduled tasks - stop file = off");

                        exit();
                  }
                  else {
                        LOG("MSG", "scheduled tasks stopped");                        
                        # Stop scheduled tasks
                        die "Crontab: scheduled tasks stopped!\n";
                  }
            }
            
      close (DAT);
}

#########################################################################
#                                                                                                            #
# Log activity                                                                                          #
#                                                                                                            #
#########################################################################

sub LOG {

      my ($type, $message) = @_;

      my ($file, $header);
      if ($type eq "ACT") {
            return unless ($log);
            $file = $logfile;
            $header = "cron";
      }
      elsif ($type eq "MSG") {
            return unless ($logmsg);
            $file = $logfile;
            $header = "cron";            
      }
      elsif ($type eq "ERR") {
            $file = $errfile;
            $header = "cron error";      
      }
                  
      # mon = 0..11 and wday = 0..6
      my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
      $mon++; # to get it to agree with the cron syntax
      $year = $year + 1900;

      open(FILE,">>$file") or die "Can't open log file: $file: $!\n";
            printf FILE "$header*[%02d/%02d/%02d %02d:%02d:%02d]: $message\n",$mon,$mday,$year,$hour,$min,$sec;
      close(FILE);
}

1;
 
Can someone tell me how do that?
0
 
LVL 84

Expert Comment

by:ozo
ID: 7291775
You could try backgrounding the program with:
    fork && exit;
0
 

Author Comment

by:mmcw
ID: 7292121
Where to add those lines?
0
 
LVL 84

Expert Comment

by:ozo
ID: 7293444
I'd say just before
# Start cron
start_cron();
0

Featured Post

The Eight Noble Truths of Backup and Recovery

How can IT departments tackle the challenges of a Big Data world? This white paper provides a roadmap to success and helps companies ensure that all their data is safe and secure, no matter if it resides on-premise with physical or virtual machines or in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
perl script 4 108
perl CPAN issue 3 109
Replace  text in a file 2 109
quoting a comma separated list 20 84
In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question