PDA

View Full Version : Perl cron job



dantheman50_98
04-17-2008, 02:20 AM
Hi everyone, I am having trouble getting a cron job to work.
I have discussed this in great detail at:

http://forums.geckotribe.com/viewtopic.php?t=2070

and I have liaised with a member of staff at westhost, so the folder it is in is fine, as the necessary .htaccess file is in place.

This is the code:

#!/usr/bin/perl

use Socket;
$hostname='musicultra.com';
$remote_host='musicultra.com';
$sockaddr = 'S n a4 x8';
$proto=getprotobyname('tcp');

($name, $aliases, $type, $len, $thisaddr) = gethostbyname($hostname);
($name, $aliases, $type, $len, $thataddr) = gethostbyname($remote_host);

$this = pack($sockaddr, &AF_INET, 0, $thisaddr);
$that = pack($sockaddr, &AF_INET, 80, $thataddr);

socket(S, &AF_INET, &SOCK_STREAM, $proto)||die "socket: $!";
bind(S,$this)||die "bind: $!";
connect(S,$that)||die "connect: $!";
select(S); $|=1; select(STDOUT);

print S "GET /celebsusa/bgcache/update_actors.php HTTP/1.0\nHost: $remote_host\n\n";
while ($line=<S>) { }
close(S);
exit 0;

When I try to run it in a browser I get "500 Internal Server Error".
So basically, can anybody see anything wrong with it?


Thank You,
Dan

bruce.binder
04-17-2008, 03:41 PM
Dan:

If I read this (and the other forum) right, you wish to periodically retrieve a web page from musicultra.com so that it remains in cache. You mention setting up a cron job to run this script, but then you refer to running this in a browser. Either I am confused or you are about what you are trying to do.

A script run as a cron job is completely independent of a web server or browser. The cron process runs on your Westhost account and, if you set it up correctly, will execute this script periodically. This script appears to have no output to STDOUT. That's fine and is probably what you want your cron job to do, since it will execute with no human intervention.

If you wish to run this script from a browser, that's a different story. Your web server will execute this script and send the output back to the browser. Since this script has no output, your web server thinks it's an error when it reaches the exit call and it has nothing to send back to the browser. I think that's the error you are seeing: Premature end of script headers.

If you really do want to run this from a browser (as opposed to cron), I recommend adding this line, just before the exit:


print "Content-type: text/plain\n\nJob complete.\n";

That way, it produces output so you shouldn't get the "premature end of script" error. If there is another error with the script, you should be able to see the error in the /var/log/httpd/error_log file.

If you really do want to run this from cron, you should try running this script from the command line first (using ssh) instead of using a browser. Then when you're sure it works, add it to your crontab.

I hope this helps,
--
Bruce

P.S. If you really just want to periodically retrieve a web page, I recommend the 'wget' or 'curl' programs. I believe both are installed on Westhost and do in one line of code what your script does in 20+.

allyn
04-17-2008, 10:29 PM
why would you run this script from a browser? that makes no sense.

i second bruce.binder's suggestion of wget if that's all you're trying to do in your script.

wget -O - http://musicultra.com/celebsusa/bgcache/update_actors.php

i think the bind is causing a problem, at least it did when i cut and pasted your script to my local system. i would remove it.

dantheman50_98
04-18-2008, 07:48 AM
Sorry, I should have explained why I was running it in the browser. Because it wouldn't work, I was trying to get some kind of result other than an error by running it in the browser, as sort of suggested by Antone, of Carp fame (the bloke directing me on the forum I linked to in my first post).

This script was taken from

http://www.geckotribe.com/rss/carp/manual/example_refresh.php

and has been used successfully by others, so should really work.

I tried removing the bind but it didn't make the bindest bit of difference (sorry!)

So, I went in search of either wget or curl on the server and neither are anywhere to be seen. Nor can I see them in the file manager.

Am I being blind?

If wget is there, how would I configure the script to run every, say, 45 minutes for example?

Thank you for the replies, chaps.

Regards,
Dan

bruce.binder
04-18-2008, 01:47 PM
Dan:

How did you search for wget and curl? On my account they are installed in /usr/bin.

When you removed the 'bind' call, are you saying you got the same result in the browser? I believe you will always get the same result in the browser because your script sends no output.

My first suggestion, if you haven't done this already, is to become familiar with running scripts and programs from the command line. You will need an ssh client to do this. There are other threads (and I think wildjokerdesign has a web page) that describe this. This would allow you to do what I did, and what allyn did, which was to run your script and see the error being genrated -- a permission problem with running the 'bind' statement.

It's from the command line that you would be able to run the 'wget' or 'curl' commands. Allyn shows an example of the command to run to retrieve a file from a web site:
wget -O - http://musicultra.com/ [whatever...]

If you really want to run your script from the browser, then you'll need to be able to view the /var/log/httpd/error_log to see any errors generated and you'll need to add the line I suggested to make sure your script outputs something. The permission issue sure sounds like Westhost (or our perl installation) does not allow access to the bind call or to the port you're trying to access.

In order to run something periodically, you add that command (wget or your script) to the crontab file. This tells the cron program to run your command at the interval you specify. You should probably do a little reading about cron and crontab.

--
Bruce

dantheman50_98
04-24-2008, 02:30 PM
Okay, well I have spent some time familiarising myself with puTTY, cron and crontab.

In PICO (the program that comes up after I enter crontab-e in puTTY) I have entered

*/2* * * * /var/www/html/celebsusa/bgcache/update_actors.php

and saved it. This is to make the script run every 2 minutes. However, it isn't working.

I have also done a separate cron job attempt with

1-59 * * * * wget http://www.musicultra.com/celebsusa/bgcache/update_babies.php

Unfortunately this also has failed to work.

Am I missing something?

Cheers chaps,
Dan

bruce.binder
04-26-2008, 09:20 AM
Dan:

I'm not positive, but I think that when cron runs, it does not load your environment or path settings. What that means is that it can't find the wget command without the full path. I would try:


1-59 * * * * /usr/bin/wget http://www.musicultra.com/...

For your first example, I think the problem is that you cannot run the .php file by itself. You need to run the php command with your script as a parameter. I would try:


*/2* * * * /usr/bin/php /var/www/html/celebsusa/bgcache/update_actors.php


I hope this helps,
--
Bruce

dantheman50_98
05-08-2008, 09:45 AM
Thanks for that Bruce.
As of yet though, it is not working. When I save the cron job, it saves into the directory /var/spool.

Is this ok?

Cheers,
Dan

bruce.binder
05-08-2008, 07:19 PM
Dan:

When you edit the crontab file, you should be using the command "crontab -e". When you save the file and exit, the file should be saved in /var/spool/cron/yourusername.

I think you should also use the "wget" command that allyn suggested, the one with "wget -O" so that it won't try to create a file every time cron runs. It may be this is failing because cron doesn't have permission to save the file.

This will send output to stdout:

/usr/bin/wget -O - http://musicultra.com/...

This will generate no output at all and is probably better:

/usr/bin/wget -O /dev/null http://musicultra.com/whatever 2> /dev/null

I suggest you remove the php command for now and just concentrate on getting the wget command working.

--
Bruce

dantheman50_98
05-11-2008, 02:42 AM
Hello again and thanks for the reply.

I seem to have got the following working :

*/2 * * * * /usr/bin/php /usr/local/apache/celebsusa/bgcache/update_news.php

But when I repeat the same command for a different php file on the next line, for example:
*/2 * * * * /usr/bin/php usr/local/apache/celebsusa/bgcache/update_news.php
*/2 * * * * /usr/bin/php usr/local/apache/celebsusa/bgcache/update_pets.php


the update_news.php file continues to work but the update_pets.php doesn't work. Am I correct in putting them all in the same crontab? I was under the impression that there is only the one crontab anyway.

As for your previous post, I am a little confused as to how I can tell if a wget command is working without using the php command.

Thanks again,
Dan

bruce.binder
05-11-2008, 11:45 AM
Dan:

I really think either you or I am missing the concept of what you are trying to do.

If I read your posts on the other forums correctly, you are running CaRP to cache a bunch of RSS feeds. You want to make your page load faster for visitors by making sure you have loaded all the RSS feeds yourself. If you do this periodically this will cause the newsfeeds from other sites that you display on your page to be cached.

To do this, you must cause a similar page to be loaded and run by your web server. The way to do this is to periodically make a web server request. The two ways suggested to make a web server request are

a. Run the perl script you originally posted -- it connects to port 80 and makes a http request through a socket.

b. Run the wget command and it does essentially the same thing.

(a) does not work on Westhost due to a permission limitation opening or binding a socket. That leaves (b).


As for your previous post, I am a little confused as to how I can tell if a wget command is working without using the php command.

You cannot tell if a wget command is working with the php command. The php command is just another way to run the same php script. However, the php command, run on the command line or by cron, will not cause the web server to load or run the page. I do not think it helps you in any way. I may be wrong about that, but the CaRP help page specifically mentions loading and running the page through the web server.

If you want to make sure your wget command is working, check the http log file in /var/log/httpd/access_log. It should show an entry every two minutes for the page request run by cron.

Cron is tricky. It runs automatically, without intervention, and with limited permissions. You can't see what it's doing and you can't interact with it while it's doing it. Make sure your command (wget or whatever) does what you want it to do successfully before adding it to crontab.

If none of this helps, then I guess I am misunderstanding what you are trying to do. I suggest you contact the folks at CaRP for further clarification. The folks on that forum know more about CaRP. If you let them know that you can't run the perl script, but you've been advised that you can run wget to do the same thing, perhaps they can help.

--
Bruce