CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Script will run forever

 



mmcw2201
User

Sep 18, 2002, 11:22 AM

Post #1 of 7 (1148 views)
Script will run forever Can't Post

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!


Code
   

#!/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?


thebitch
User

Sep 18, 2002, 1:29 PM

Post #2 of 7 (1144 views)
Re: [mmcw2201] Script will run forever [In reply to] Can't Post

well the reason is because it is not a
CGI script, and should not be run as one.

just run it from the commandline.

you could use `fork', to do what you want,
but that'd could get you in trouble in a heartbeat.

just run it from the commanline like it was supposed to be run.


mmcw2201
User

Sep 18, 2002, 9:19 PM

Post #3 of 7 (1141 views)
Re: [thebitch] Script will run forever [In reply to] Can't Post

I do not have command line access! That's why I am trying to start it from my browser. Could you give it a try to use the fork option?


(This post was edited by mmcw2201 on Sep 18, 2002, 9:40 PM)


thebitch
User

Sep 19, 2002, 2:47 AM

Post #4 of 7 (1137 views)
Re: [mmcw2201] Script will run forever [In reply to] Can't Post


In Reply To
I do not have command line access! That's why I am trying to start it from my browser. Could you give it a try to use the fork option?


You really should get commandline access!!!!!!!!!!!!!!!

If u don't have it, chances are you're not supposed to be
running any daemons (cron).

Chances are, you could lose your account very soon.
But i don't care Wink

put this before alll that other code and pray


Code
 
BEGIN {
my $kid = fork;
die "couldn't fork " unless defined $kid;
exit(0) if $kid; # we got a zombie, so parent away

## and now we're in the zombie
mkdir __FILE__.'.zombie' or die "perlcron already running";

END {
## when shutting down, as CFS() directs

rmdir __FILE__.'.zombie' or die "eek, WTF? $!";
}

}



(This post was edited by thebitch on Sep 19, 2002, 2:49 AM)


mmcw2201
User

Sep 19, 2002, 3:40 AM

Post #5 of 7 (1133 views)
Re: [thebitch] Script will run forever [In reply to] Can't Post

I have changed my code to but it still seem to load forever?

Code
   

sub start_cron {

BEGIN {
my $kid = fork;
die "couldn't fork " unless defined $kid;
exit(0) if $kid;
# we got a zombie, so parent away
## and now we're in the zombie
mkdir __FILE__.'.zombie' or die "perlcron already running";

END {
## when shutting down, as CFS() directs
rmdir __FILE__.'.zombie' or die "eek, WTF? $!";
}
}

# return and let child do the work
if (fork) {
exit(0);
}

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

unless ($silent) {
# Print to screen
print "Crontab: scheduled tasks [$$] started.<br>\n";
}

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

........

......

....

...

..

.



(This post was edited by mmcw2201 on Sep 19, 2002, 3:46 AM)


thebitch
User

Sep 19, 2002, 11:25 PM

Post #6 of 7 (1125 views)
Re: [mmcw2201] Script will run forever [In reply to] Can't Post

 
try closing stdin and stdout.
if that doesn't work, well, tough noogies.

The child shouldn't do any printing.
The child is the zombie.
Understand fork before you continue.


thebitch
User

Sep 20, 2002, 1:09 AM

Post #7 of 7 (1123 views)
Re: [mmcw2201] Script will run forever [In reply to] Can't Post

you know what, forget all that fork BS.

just do

Code
exec '/path/to/perlcron'


 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives