homepage Welcome to WebmasterWorld Guest from 54.166.113.249
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
Forum Library, Charter, Moderators: coopster & jatar k & phranque

Perl Server Side CGI Scripting Forum

    
run scripts each hour withour cron
run scripts each hour withour cron
StopSpam

10+ Year Member



 
Msg#: 3125 posted 1:46 am on Jul 11, 2003 (gmt 0)

is there a way to run a perl script every hour
without using cron job ...

i mean can a different script replace cron job and run a nother script each our .

or can i add a timer to a script so it eclute each hour

with out taking all system memorie

 

sugarkane

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 3125 posted 9:59 am on Jul 11, 2003 (gmt 0)

You *could* put the script in an infinite loop, including a sleep command to make it pause for an hour after doing whatever it is that the script does.

while (1) {
# do your stuff here
sleep 3600;
}

But this would have disadvantages compared to cron - eg if the script failed in some way, it would stop it executing all the subsequent times the hour rolled around rather than just failing in that one instance. You'd also have to be very careful to clear variables etc at the end of each loop or you'd end up experiencing memory problems and/or unexpected results.

Is cron not available to you on your host?

Damian

10+ Year Member



 
Msg#: 3125 posted 10:13 am on Jul 11, 2003 (gmt 0)

It's not pretty, but another way to possibly do what you want if it's a web based headlines type of script:

- Have your main script generate a static file with it's output when it runs. (ie. the headlines of a news source)
- Load a script with each call of the page that is supposed to show the main script, and check the age of the static file generated by your main script. If it's less then an hour old use that, otherwise run the main script again before you use the static file.

StopSpam

10+ Year Member



 
Msg#: 3125 posted 10:42 am on Jul 11, 2003 (gmt 0)

No my hosting company said i cant use cron ...
they do not support it ... strange is it ...

the sleep loop i like to avoid as it has memorie risks
if i make sloppy code as i do as beginner.
server can easy crash on memorie run out ...

yeh run script based on as soon it gets requested could be done then i can use sleep without a loop

when site is called run script then sleep 3500
then next visitors activates it again

how can one script start a nother script?

Damian

10+ Year Member



 
Msg#: 3125 posted 12:30 pm on Jul 11, 2003 (gmt 0)

If the script can be triggered by visitors to your site, you might want to change the main script:
Instead of doing what it usually does when triggered, it could first check the age of a static file containing the output of the script from within the last hour, return that as output, or, if the static file is more then one hour old, update the static file and then show the contents of that file.

In that case you don't need one script to trigger another, but you would need to change the behaviour of your mainscript to give output based on the static file.

'sleep' would not be needed at all in this scenario.

>how can one script start another script?
You can write something like this in the script that should trigger myscript.cgi:

require "home/cgi-bin/myscript.cgi";

StopSpam

10+ Year Member



 
Msg#: 3125 posted 12:55 pm on Jul 11, 2003 (gmt 0)

i like what you write ...

script 1 checks how old (minutes) a time.txt file is .
if older then 1 hour then run sub next

how can a script check how old a file.txt is?
thats all new to me ,i thit not even know that where posible ;-)

yeh no need for sleep and no memorie drops this way ....

Damian

10+ Year Member



 
Msg#: 3125 posted 1:08 pm on Jul 11, 2003 (gmt 0)

One way to check the age of a file below..
I do remember there was an easier way to tell the age of a file but I don't recall the exact syntax. My sample below uses 'stat'

[perl]
# Update interval in seconds
$interval = 1800;

# current time
$now = time;

#if the file exists, get it's properties
if ( -f file.txt) {
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat(file.txt);
$difference = $now - $mtime;
}

# trigger the "Update" sub routine (not included in this example) to create a new copy of file.txt
if ( $difference > $interval !-f file.txt) {&Update(file.txt);
[/perl]

This board changes the pipe characters, so change the split pipes back to regular pipes in the code above

claus

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 3125 posted 1:31 pm on Jul 11, 2003 (gmt 0)

Damian, the $mtime is # 10 in "stat", so you could reference it like this (starting from 0 as usual):

$lastUpdate = (stat($file))[9];

#if the file exists, get it's properties
if ( -f file.txt) {
$lastUpdate = (stat(file.txt))[9];
$difference = $now - $lastUpdate;
}

- this adds nothing new, it's just another way. What i wanted to say was, that i would prefer this order to things:

1) check time
2) deliver page
3) if time is due, then run update.

That is: Not in the order 1,3,2 as suggested above.

This way the person that hits the page at the time of update will get the latest page delivered without having to wait for the update to finish. Then, a later visitor will get the updated page, but it will be delivered faster.

/claus

sugarkane

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 3125 posted 1:39 pm on Jul 11, 2003 (gmt 0)

$lastUpdate = (stat($file))[9];

Very slick Claus, I've not come across that construction before... I've always used the same method as Damian and never thought to do it that way. Thanks.

StopSpam

10+ Year Member



 
Msg#: 3125 posted 2:01 pm on Jul 11, 2003 (gmt 0)

#!/usr/local/bin/perl

# Update interval in seconds
$interval = 1800;
# current time
$now = time;

#if the file exists, get it's properties
if ( -f time.txt) {
$lastUpdate = (stat(time.txt))[9];
$difference = $now - $lastUpdate;
}

# trigger the "Update" sub routine (not included in this example) to create a new copy of time.txt
if ( $difference > $interval?!-f time.txt) {&Update(time.txt);

sub Update {

open(FILE, "> time.txt") or die " Cant open time.txt: $!";
print FILE "";
close(FILE);

}

Thank all this looks good ..

i made sub Update . it reads time.txt delete all lines
its not making new file justclear all is in, but this gives also new time to the file right?
as last time used is now time that sub Update clean it?

if i try this the script would only run sub Update if the file is older then $interval = 1800;
am i right?

Damian

10+ Year Member



 
Msg#: 3125 posted 2:20 pm on Jul 11, 2003 (gmt 0)

Thanks claus, nice notation and good point about the order.
I guess the order depends on what's most important..speed or being up to date. For a news related script it may be more important to show the latest news then to have a quicker website.

I just remembered the other way to get a file's age is

$days_old = -M file.txt;

It returns the number of days file.txt is old. (with a lot of number behind the comma) So if $days_old would be > 0.0416 the file is older then an hour approximatly.

Stopspam, there's a bracket missing at the end of this line (my mistake)
{&Update(time.txt);
it should be {&Update(time.txt);}

>if i try this the script would only run sub Update if the file is older then $interval = 1800;
> am i right?

Right, just write the output of your script to file.txt where you clear it now, and serve the content of file.txt to your visitors instead of 'live' output from the script.

killroy

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 3125 posted 2:44 pm on Jul 11, 2003 (gmt 0)

I'm currently testing a system where the script is accessible vie hte webserver, and the cron runs on a local computer, simply calling the website once per hour.

SN

claus

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 3125 posted 5:33 pm on Jul 11, 2003 (gmt 0)

order of things... i thought it was something a bit more complicated than touching a file, so just forget it again ;) nice workaround running the cron from outside though :) /claus

StopSpam

10+ Year Member



 
Msg#: 3125 posted 3:08 pm on Jul 13, 2003 (gmt 0)

will debugging the code iget a error :

14 # trigger the "Update" sub routine (not included in this example) to create a new copy of time.txt
15 if ( $difference > $interval?!-f time.txt) {&Update(time.txt);}
Line 15 syntax error at /home/web/www/cgi-bin/robot/timeclean.cgi line 15, near "txt) "

claus

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 3125 posted 10:42 am on Jul 14, 2003 (gmt 0)

Check Damians post #7. It's not "$interval?!-f time"

- there's a space after $interval

- then a pipe (you can not copy this one : ¦ it needs to be typed from the keyboard so it will not be split. You have a questionmark here.

- then the rest.

Hope it helps.

/claus

StopSpam

10+ Year Member



 
Msg#: 3125 posted 12:21 pm on Jul 14, 2003 (gmt 0)

I cant get it to work;-(

Debugging goes ok i get a nice script OK!

but when i try to run the script i get a Internal Server Error ....

i think its the part to get the time: $now = time;
should i add time to the script like;

$date = scalar localtime ( time ); ?

here is code i used but fails ...
i had chmod the time.txt file 666

#########

#!/usr/local/bin/perl

$interval = 1800;
# current time
$now = time;

if ( -f time.txt) {
$lastUpdate = (stat(time.txt))[9];
$difference = $now - $lastUpdate;
}
if ( $difference > $interval ¦!-f time.txt) {&Update(time.txt);

print " time past $difference\n";

sub Update {

open(FILE, "> time.txt") or die " Cant open time.txt: $!";
print FILE "";
close(FILE);

print " time past $difference has pasted file is cleaned\n";

}
}

Damian

10+ Year Member



 
Msg#: 3125 posted 12:55 pm on Jul 14, 2003 (gmt 0)

StopSpam..

There's an error in your script above with the placement of brackets.

- Remove the last closing bracket, and add it to the line below

Also please try to put the time.txt between quotes, I think that's what caused your error initially before you went debugging ;) Sorry..

- change this line
if ( $difference > $interval ¦!-f time.txt) {&Update(time.txt);
to
if ( $difference > $interval ¦! -f "time.txt") {&Update;}

I removed the reference to time.txt in &Update(time.txt) because it serves no purpose in your Update sub routine.

StopSpam

10+ Year Member



 
Msg#: 3125 posted 2:18 pm on Jul 14, 2003 (gmt 0)

Damian that works but not all ...

i use this code:
and all it do is grap print $now that works
it aint print $lastUpdate or $difference its
like the script ends here or server dont know what to return?

i added all print lines so ican see if each functionworks .. it only prints $now

#!/usr/local/bin/perl

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

$interval = 1800;
$now = time;

print " print now: $now\n\n";
print "\n\n";

if ( -f time.txt) {
$lastUpdate = (stat(time.txt))[9];
$difference = $now - $lastUpdate;
}
if ( $difference > $interval ¦! -f "time.txt") {&Update;}

print " print last update: $lastUpdate \n";
print " show difference: $difference\n";

sub Update {

open(FILE, "> time.txt") or die " Cant open time.txt: $!";
print FILE "";
close(FILE);

print " diff is; $difference file time.txt has been cleaned!\n";

}

#######

i also found this using google:

#!/usr/bin/perl
$now = time;
utime $now, $now, @ARGV;

whats the utime $now, $now,?
should i use it?

Damian

10+ Year Member



 
Msg#: 3125 posted 4:01 pm on Jul 16, 2003 (gmt 0)

OK..sorry for the sloppy code. I tried to explain a concept and didn't pay enough attention to the exact syntax..The below should work..it works on my win32 machine:

[perl]
#!D:\perl\bin\perl.exe
use CGI::Carp qw(carpout fatalsToBrowser);
print "Content-type: text/html\n\n";

$interval = 2;
# current time
$now = time;

if ( -f "time.txt") {
$lastUpdate = (stat("time.txt"))[9];
$difference = $now - $lastUpdate;
}
if ( $difference > $interval ¦!(-f "time.txt")) {&Update; }

print " time past $difference\n";

sub Update {

open(FILE, "> time.txt") or die " Cant open time.txt: $!";
print FILE "";
close(FILE);

print " time past $difference has passed file is cleaned\n";

}

[/perl]

StopSpam

10+ Year Member



 
Msg#: 3125 posted 6:28 pm on Jul 18, 2003 (gmt 0)

Damian thanks the code works its cool...
i g try builth it in a nother script

jdMorgan

WebmasterWorld Senior Member jdmorgan us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3125 posted 7:19 pm on Jul 18, 2003 (gmt 0)

Coming late to the party, but intentionally so as not to divert the thread...

In the final version, we still have:

if ( -f "time.txt") {

and then later, this:

if ( $difference > $interval !(-f "time.txt")) {&Update; }

I just wanted to note that this construct requires two checks to see if the file exists - usually an inefficient process, since it involves the file system. It would be better/faster to check once, set a var, and then use that var for all subsequent checks. Or just restructure the code so that a second check for the existence of time.txt is not needed.

That said, thanks to all for the collaborative code snippet, several good tricks there... Copied into my "library" already. :)

Jim

StopSpam

10+ Year Member



 
Msg#: 3125 posted 11:58 am on Jul 19, 2003 (gmt 0)

Its never to late to join ....

can you show me a sample of the code you mention in:

It would be better/faster to check once, set a var, and then use that var for all subsequent checks.

faster is better script i think ...

Damian

10+ Year Member



 
Msg#: 3125 posted 12:28 pm on Jul 19, 2003 (gmt 0)

Jim's right. Even better would of course be to simply make sure that time.txt exist before running the script, so we don't have to check that at all. It depends on what you need it for but if there's just one file that needs to be checked, checking it's existence at all is overdoing it.

In case there are more files, which may not exist yet, I think this is what Jim has in mind more or less. My example uses the variable $file_exists, which is set to 1 if the file exists. I changed the occurences of 'time.txt' into a the variable $file because that's a more realistic situation when dealing with multiple files that need to be checked, and it changes the syntax slightly with the usage of quotes.
I also made some changes to the printed text to make a little more sense :)

[perl]

#!E:\perl\bin\perl.exe
use CGI::Carp qw(carpout fatalsToBrowser);
print "Content-type: text/html\n\n";

#interval time in seconds
$interval = 2;
# current time
$now = time;

# the static file
$file = "time.txt";

my $file_exists = 0;

if ( -f $file) {
$file_exists = 1;
$lastUpdate = (stat($file))[9];
$difference = $now - $lastUpdate;
}

if ( $difference > $interval ¦ $file_exists == 0) {&Update; }

print "Time passed $difference\n";

sub Update {

open(FILE, "> $file") or die " Cant open $file: $!";
print FILE "";
close(FILE);

print "$file was updated<br>\n";

}

[/perl]

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved