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
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
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
#!/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
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.
Cron does not recognize globals I pass through, command line, terminal, Perl editor and httpd DO!
Cheers,
Ton
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.
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.
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.
#!/opt/local/bin/perl -wuse 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.
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.
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";
}