Welcome to WebmasterWorld Guest from 54.166.220.138

Forum Moderators: coopster & jatar k & phranque

Message Too Old, No Replies

Cron and global values

     
8:58 am on Aug 18, 2009 (gmt 0)

10+ Year Member



Hiya,

I am using about 20 Perl scripts and libraries for all kinds of user and admin actions in a website. All scripts first load an external 'master' library. In this library I declare a lot of globals and paths to directories I need in all orher scripts and libraries I call. This setup works like a dream because I can change all global for all other scripts and libraries with just 1 'master' librarie. It also works from the editor, from the terminal and from http. But, last night I noticed that this setup does NOT work with cron.

In all scripts I first load the 'master library that is in the same directory'. Here I set my paths and other important 'global' globals. Example: $Perl_Doc_Dir = qq(/Library/WebServer/Documents/my_directory);

Then I use the '$Perl_Doc_Dir' global to point to directories, external libraries and files. Like 'chdir $Perl_Doc_Dir/foo/bar'.

Cron does not recognize my '$Perl_Doc_Dir'?. So my guess is that globals are not transferable between scripts launched from cron?

I hope some of you can point me to the right direction.

Thanx,

Ton

10:03 am on Aug 18, 2009 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



Could it be that the perl-scripts cannot include the "master library" because they're started by cron, not by the httpd and have a different current working directory. Did you require the library with an absolute path or just
require "master.lib.pl"; ?
10:21 am on Aug 18, 2009 (gmt 0)

10+ Year Member



Hi, yes I require the 'master library' with an absolute path. It works from the command line, terminal and httpd. Just not in cron. It feels like the scripts 'forget' to transfer the global values to eachother.

Btw, all scripts and libraries are it the same directory but I need to read and write a lot from and in different directories so I need to chdir a lot!

Ton

10:30 am on Aug 18, 2009 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



mh, so it requires the library and succeeds but does not correctly run the code in there?

can you break it down to a minimal test case that still works the way the big thing works but can be posted here?

10:46 am on Aug 18, 2009 (gmt 0)

10+ Year Member



Hi,

here is the main script: cron-test

# start -------------------------

#!/opt/local/bin/perl -w

$Err_Mess = "";

if ((!do "lib-set-globals.pl")) {
$Err_Mess = qq(Missing library 'lib-set-globals.pl');
}

print "$Perl_Doc_Dir/mydir/mysubdir";

print "\nDone!";

exit;

# end -------------------------

And the library: lib-set-globals.pl

# start -------------------------

$Perl_Doc_Dir = qq(/Library/WebServer/Documents/my_directory); # Path for Perl to http docs

# end -------------------------

Output from terminal or editor:
/Library/WebServer/Documents/my_directory/mydir/mysubdir
Done!

Output from cron:
/mydir/mysubdir
Done!

Cheers,

Ton

11:03 am on Aug 18, 2009 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



mh, "do" won't throw an error if it cannot open the file it is told to load, which could fail because the file does not exist or the user running the script does not have the necessary access privileges (which could already be the solution to your problem).
try require instead of do, it will die with an error message unless it can execute the code in the file.
11:19 am on Aug 18, 2009 (gmt 0)

10+ Year Member



All fille permissions are okidoki. I tried the require method instead of 'do' but that doesn't doe the job;-( Btw, "do" does throw an error in my setup;-)

#!/opt/local/bin/perl -w

print "\nStart\n";
require "lib-set-globals.pl";
print "$Perl_Doc_Dir/mydir/mysubdir";
print "\nEnd\n";
exit;

Output:
nothing at all!

----------------------------------------

#!/opt/local/bin/perl -w

print "\nStart\n";
do "lib-set-globals.pl";
print "$Perl_Doc_Dir/mydir/mysubdir";
print "\nEnd\n";
exit;

Output:
Start
/mydir/mysubdir
End

Ton

5:44 pm on Aug 18, 2009 (gmt 0)

WebmasterWorld Senior Member rocknbil is a WebmasterWorld Top Contributor of All Time 10+ Year Member



yes I require the 'master library' with an absolute path.

Is this it? If so, doesn't appear you do, but in any case try changing

require "lib-set-globals.pl";

to

require "/full/system/path/to/lib-set-globals.pl";

When your cron is run, it may not be running the program from the local directory of the script.

11:16 pm on Aug 18, 2009 (gmt 0)

10+ Year Member



Well, that is the problem, please read my first post. I want to use 1 'master library for 'global' environment settings. I am going to sell the project and the customer should be able to set all desired parameters for the website, company, scripts locations, path names, you name it from only 1 place.

Cron does not recognize globals I pass through, command line, terminal, Perl editor and httpd DO!

Cheers,

Ton

11:33 pm on Aug 19, 2009 (gmt 0)

WebmasterWorld Senior Member rocknbil is a WebmasterWorld Top Contributor of All Time 10+ Year Member



I did, and still think your problem is in the require. Case in point,


Output:
nothing at all!

Not even a warning from -w? Or anything in the error log? (Which may not record an error if run via cmd line or cron . . . ) At the very least you should get an error to STDOUT if not found, or the Start and End. But no output at all is odd.

Can you access any cron logs on your server? Might give a clue.

I notice you're using chdir, maybe it's related to that; you shouldn't need a process to change directory in most cases and maybe this is mucking up the works.

Your globals have to come from *somewhere* and the include line needs to point to the full path of the global include to get them, doesn't matter where on your system it executes, or by what, httpd, cmd, or cron. Maybe what you can do in distributing the programs is create an install script that writes the full path for you from source files.

2:14 am on Aug 20, 2009 (gmt 0)

10+ Year Member



Thanx rocknbil, I will think about it. I am trying to make the product as easy as possible by using just 1 config file. For now I will just continue working and debugging because it is just the cron jobs that are failing. I am sure I will find the problem soon or later.

Thanx all;-)

Ton

7:40 am on Aug 21, 2009 (gmt 0)

WebmasterWorld Administrator phranque is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



maybe i missed it in one of your posts but on what OS are you trying this?
7:47 am on Aug 21, 2009 (gmt 0)

10+ Year Member



Hiya, working on OS X

Cheers,

Ton

10:22 am on Aug 21, 2009 (gmt 0)

WebmasterWorld Administrator phranque is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



what you are describing (a limited set of environment variables) is the defined behavior for cron in most *nix-like systems and i assume for OS X as well.
you might consider looking into launchd for your purposes.

[edited by: phranque at 7:46 pm (utc) on Aug. 21, 2009]

11:00 am on Aug 21, 2009 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member




what you are describing (a limited set of environment variables) is the defined behavior for cron in most #nix-like systems and i assume for OS X as well.
you might consider looking into launchd for your purposes.

I don't think that's the issue. He seems to be storig his configuration in a simple perl-file where he just sets some variables and requires (or "do"es) this file from all of his scripts (probably not using strict). I still think it's a path-issue and the error-mails from cron just don't get through.

4:37 pm on Aug 24, 2009 (gmt 0)

WebmasterWorld Administrator brett_tabke is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



#!/opt/local/bin/perl -w

print "\nStart\n";
require "lib-set-globals.pl";
print "$Perl_Doc_Dir/mydir/mysubdir";
print "\nEnd\n";
exit;


Where are you setting the CWD?

require "lib-set-globals.pl";

How is that file even being found? Cron will call it from root (or etc). You have to call that with an abs path. The webserver will set the root of the site to the CWD when it calls the screen. A cron job will set the CWD to something else.

5:25 pm on Aug 24, 2009 (gmt 0)

10+ Year Member



Hiya, in all cron scripts I have set my header like this:

#!/opt/local/bin/perl -w

use DBI;
use Cwd;
use CGI qw(:all);
use LWP::Simple qw(get);
use Net::SMTP;
use Time::HiRes qw(gettimeofday);

Cheers,

Tob

6:39 pm on Aug 28, 2009 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



maybe changing that to

#!/opt/local/bin/perl -w

use DBI;
use Cwd;
use CGI qw(:all);
use LWP::Simple qw(get);
use Net::SMTP;
use Time::HiRes qw(gettimeofday);
use FindBin::Real;
chdir(FindBin::Real::Bin());

will get rid of your problem. It's not the "right" way to do it, but it'll probably let you continue in the way you're working now.

7:48 pm on Aug 29, 2009 (gmt 0)

WebmasterWorld Administrator brett_tabke is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



Ya, you still have to chdir into the right directory for that script. It isn't finding it.
9:28 am on Aug 30, 2009 (gmt 0)

10+ Year Member



Hi, Brett, do you mean that even if cron launched the first script from the root directory I need to tell Cron to launch my 'lib-set-globals.pl' from the same directory using Cwd?

Ton

1:58 pm on Sep 2, 2009 (gmt 0)

WebmasterWorld Administrator brett_tabke is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



Not sure Parrot. I may be understanding where you have paths. Sure sounds like a path issue.

To figure out what is going on - create a couple quick test scripts that get called from cron. Have them write a log file of what the current cwd is. Then put them in you same directories, set your con to something low like every minute and wait. Tweak it to suit.

4:20 am on Sep 12, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



My first thought was detect if it's a cron job. I haven't tested this, but did a little research and it appears the cron job would have no $ENV(REMOTE_ADDR) value set, you could throw some code in the scripts to detect if it's a cron job or not, then pick from the paths you've specified in the "globals" file, e.g.-

lib-set-globals.pl contains-

#
$pathFromRoot1 = '/server/123/abc/user/images/';
$relativePath1 = '/images/';
#

then, all scripts contain-

if ($ENV{REMOTE_ADDR} eq "") {
$thePath = "$pathFromRoot1";
} else {
$thePath = "$relativePath1";
}

 

Featured Threads

Hot Threads This Week

Hot Threads This Month