tags:

views:

836

answers:

6

I have a bunch of Perl scripts that all run fine, yet need to have use Plibdata; up top.

I set up a cron job that runs (I get the confirmation email from root) and it spits back the following error message:


Can't locate Plibdata.pm in @INC (@INC contains: /install/lib /opt/perl58/lib/5.8.8/IA64.ARCHREV_0-thread-multi /opt/perl58/lib/5.8.8 /opt/perl58/lib/site_perl/5.8.8/IA64.ARCHREV_0-thread-multi /opt/perl58/lib/site_perl/5.8.8 /opt/perl58/lib/site_perl .) at ./x line 5.

BEGIN failed--compilation aborted at ./x line 5.


Line 5 is... you guessed it.... use Plibdata;

I am also attempting to set the environment as such..
use lib "$ENV{CARSPATH}/install/lib";
so maybe if I found the location of this plibdata, I could explicitly direct it that way?

My cron commands will be executed using /usr/bin/sh says crontabs....

Any suggestions?

This script works from the command line.

+7  A: 

You don't say what Plibdata is. You also don't state if this works at your command prompt. I assume that it does.

Try this:

perl -MPlibdata -e 1

Assuming that doesn't spit the same error, try this:

perl -MPlibdata -le 'print $INC{"Plibdata.pm"}'

That will tell you where. (It's probably in your PERL5LIB env var if this works.) Then you can just add the appropriate "use lib" to the directory Plibdata.pm is in.

Also, be sure you're using the same perl in both locations - command line ("which perl") and in the cron job (try "BEGIN { print $^X }" at the top of your script).

Tanktalus
those both gave me back the same error message as mentioned above
CheeseConQueso
Ok, so what does $CARSPATH contain? "echo $CARSPATH" at the command line. If that shows nothing, then you'll need to talk to your fellow developers about where it really is.
Tanktalus
And is there a /opt/carsi/install/lib/Plibdata.pm ? You'll either have to use lib "/opt/carsi/install/lib";, or use lib "$ENV{CARSPATH}/install/lib"; and find a way to set CARSPATH in your crontab or something (that becomes a new question).
Tanktalus
yeah im using that exact syntax.. the 2nd one... ill try the 1st version (essentially the same, but more explicit)thanks for all the help
CheeseConQueso
oh and yes /opt/carsi/install/lib/Plibdata.pm exists
CheeseConQueso
+6  A: 

Cron uses a different user env than your env when logged in. Are you able to run the script from the command line? If so, just set your env variables inside the cron above your current commands.

Zak
The question does seem to state that they run from the commandline. I'm pretty sure you're right about environment variables not being set.
Dana the Sane
how would i go about doing that? inside the cron.txt?
CheeseConQueso
+1  A: 

cron does not setup an environment for you when it runs your code, so the environment variable $CARSPATH does not exist. I suggest only running shell scripts from cron, setting the environment inside of the shell script and then running the program you really wanted to run.

example wrapper script:

#!/bin/bash

source ~username/.bash_profile
cd ~username
./script.pl

If you are using ksh or sh you may need to say

#!/bin/sh

. ~username/.profile
cd ~username
./script.pl

Remember to replace username with your username on the system. Also, if the script is not in your home directory you will want to execute it with the path to it, not ./.

You say source, or period space, to load a given shell script in the current shell. You load it in the current shell so that any environment settings stay with the current shell.

~/.bash_profile, ~/.bashrc, ~/.profile, /etc/profile, etc. are all files that commonly hold your environment setup. Which one you are using depends heavily on your OS and who set it up.

Chas. Owens
how can i set the environment inside a shell script? #!/bin/ksh ?
CheeseConQueso
it wont run from the command line.....interpreter "/bin/bash" not foundfile link resolves to "/usr/bin/bash".......... can it be done with #!/bin/ksh ?
CheeseConQueso
i tried a couple different combinations.... it seems that i need bash instead of ksh for the source ~CheeseConQueso/.bash_profile to work... ksh ignores it, spits an error, then runs the script normally.. and i tried .ksh_profile - no luck there either
CheeseConQueso
Yes, but change "source" to "." and ".bash_profile" to ".profile". This also assumes CheeseConQueso (with that casing) is your username on that system.
Chas. Owens
It also assumes that the script is in your home directory, you may need to change the path.
Chas. Owens
Rather than relying on the .bash_profile to set up your environment, make any script (not just Perl), handle the things it needs to setup. Either that, or make a special profile for cron, or set the environment variables, like PERL5LIB, in your crontab.
brian d foy
@chas yeah i changed the CCQ to my username and the script is in my home dir... ill try it out.. thanks
CheeseConQueso
ok now i hit another wall... when i log in, i hit a prompt to select a database or quit... so when i ran it from the command line, it brought me to that prompt. then i chose my db and it ran the script fine. set up the cron but i suppose it never got past the prompt because nothing happened
CheeseConQueso
You have a prompt in your .profile? That is not normal. Well, you are going to need to create a separate file that sets up the environment you want the shell to have and source it instead of your .profile.
Chas. Owens
+4  A: 

Clearly, Plibdata.pm is not installed in the default module paths on your system: /install/lib /opt/perl58/lib/5.8.8/IA64.ARCHREV_0-thread-multi /opt/perl58/lib/5.8.8 /opt/perl58/lib/site_perl/5.8.8/IA64.ARCHREV_0-thread-multi /opt/perl58/lib/site_perl/5.8.8 /opt/perl58/lib/site_perl

You have three choices:

  1. Install Plibdata.pm in a known perl system path (site_perl is the classic option).

  2. Make the PERL5LIB shell environment (or the equivalent command line -I option for perl) include the installation path of the module.

  3. Use "use lib" in your script. Remember that the "use lib" action is done at compile time, so your variable in the path may not be initialised. Try using the variable in a BEGIN block like this:

    my $env;

    BEGIN { $env = $ENV{CARSPATH}; }

    use lib "$env/install/lib";

Only number 1 will work. He/She is running the code under cron and therefor does not have an environment
Chas. Owens
I think I'm already doing that..... use lib "$ENV{CARSPATH}/install/lib";is also up in the use block
CheeseConQueso
CheeseConQueso: THe important part is the BEGIN block. This executes at compile time and not at run time. Both steps occur when you run perl, but in a classic strict order: compile->run. nxadm
ahhh ok thanks for the heads up... thats good to know
CheeseConQueso
A: 

Although its not an 'answer', I resolved this issue by using DBI instead of the Plibdata.

Which is kind of milky because now I will have to change a couple scripts around... ahhhhh I wish there was something I could do to make the Plibdata work

I'm still going to try Chas. Owens answer to see if that works


didn't work for me... "interpreter "/bin/bash" not found"
maybe it would work with people who have that interpreter



* * * * * CARSPATH=/opt/carsi ./x

works

CheeseConQueso
+1  A: 

Running your program from a wrapper script as others have suggested is probably my preferred method, but there may be a few other solutions:

If you're using a modern cron you may be able to do something like this in your crontab entry:

* * * * * CARSPATH=/opt/carsi x

replacing the asterisks with the appropriate schedule designators.

This will set CARSPATH for the x process and allow the use lib statement that passes the environment variable to work.

You can also, depending on your shell and cron implementation, store your environment setup in a file and do something like:

* * * * * source specialenv.sh && x

Where specialenv.sh contains lines like (for bash)

export CARSPATH=/opt/carsi

You may also be able to set environment variables directly in the crontab, should you choose to do so.

converter42
* * * * * CARSPATH=/opt/carsi x FOR THE WIN!!
CheeseConQueso