http://qs1969.pair.com?node_id=397210

TJD has asked for the wisdom of the Perl Monks concerning the following question:

I have half a dozen scripts that make up a shopping cart system. The main script calls subroutine scripts using a Require function (e.g. require "config.cgi";).

I've developed the system on a Linux server and now I've leased website space with www.omnis.com to begin final testing and production. The Omnis server is also running with Linux.

The problem: The scripts won't run on the Omnis.com server. When I try to call the system I get the dreaded 500 Internal Server Error message. To say that the Omnis technical people have been less than helpful would be a gross understatement. They loaded a three line script into my cgi-bin and ran it, reporting that the system works and that's the most they can do. They say that debugging code isn't their responsibility. I never asked them to debug the script, and they completely ignored my request for information about error messages on the server logs.

Using a script called AdminPro, I've learned that the main script is failing when it reaches the Require function that calls the configuration subroutine. That occurs at the very start of the script. The error message says:

Can't locate config.cgi in @INC (@INC contains: /etc/perl /usr/lib/perl5/site_perl/5.8.4/i686-linux /usr/lib/perl5/site_perl/5.8.4 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.4/i686-linux /usr/lib/perl5/vendor_perl/5.8.4 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.4/i686-linux /usr/lib/perl5/5.8.4 /usr/local/lib/site_perl .) line 12.

From experience I know that this message usually pops up when there's a problem with the subroutine script, but these scripts are all working perfectly on the testing server. The permissions on the new server are correct, the scripts all pass Omnis Perl checker for correct syntax, and I uploaded them correctly.

I thought that scripts within the same file directory were automatically loaded into the @INC array but I guess that I was wrong. And on the possibility that relative addressing isn't working, I changed the Require function to reflect the full path. No difference.

My questions:

1) Is the @INC array unique to each website, or is it a common array used by all websites on that server?

2) Is it possible that the server is set not to allow the use of the Require function that so people can't contaminate the @INC array with special mods?

3) Is there a way to force the loading into the @INC array?

I'll be grateful for any suggestions since the people at Omnis.com won't provide any help at all.

Thanx in advance for any help you can provide.

  • Comment on Require a script not found in @INC array

Replies are listed 'Best First'.
Re: Require a script not found in @INC array
by mifflin (Curate) on Oct 07, 2004 at 03:12 UTC
    For Question 3, see perlfaq8.
    It details a few ways to add to the INC array....
      How do I add a directory to my include path (@INC) at runtime?
        Here are the suggested ways of modifying your include path:
    
            the PERLLIB environment variable
            the PERL5LIB environment variable
            the perl -Idir command line flag
            the use lib pragma, as in
                use lib "$ENV{HOME}/myown_perllib";
    
        The latter is particularly useful because it knows about machine
        dependent architectures. The lib.pm pragmatic module was first included
        with the 5.002 release of Perl.
    
      One could also do something like this (but it is less pretty):

      BEGIN { unshift @INC, '/my/path'; }
      That is also in perlfaq8
Re: Require a script not found in @INC array
by dragonchild (Archbishop) on Oct 07, 2004 at 03:39 UTC
    The problem is that @INC contains directory names. These directory names, if they're relative paths, are relative to the directory within which the webserver is started in. Usually, this is something like /var/www or something like that. You don't normally have a problem when testing your scripts from the commandline because you're usually in the directory the scripts are in. To test this out, go to another directory and try to run your scripts. :-)

    You need to add the following line above your requires: use lib qw( /path/to/your/cgi-bin ); and that will fix everything.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      I added :

      use lib qw(/webroot/d/e/depri001/cgi-bin);

      but it still doesn't work. Here's what AdminPro says now:

      Can't locate config.cgi in @INC (@INC contains: /webroot/d/e/depri001/cgi-bin /etc/perl /usr/lib/perl5/site_perl/5.8.4/i686-linux /usr/lib/perl5/site_perl/5.8.4 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.4/i686-linux /usr/lib/perl5/vendor_perl/5.8.4 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.4/i686-linux /usr/lib/perl5/5.8.4 /usr/local/lib/site_perl .) line 14.

      The cgi-bin path appears in the @INC but it still isn't finding the config.cgi. Thanks for the try.

        Are you absolutely sure you added what 'pwd' says your directory is?

        Also, have you tried my other suggestion of running the script from somewhere other than your cgi-bin? Like, your home directory.

        Being right, does not endow the right to be rude; politeness costs nothing.
        Being unknowing, is not the same as being stupid.
        Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
        Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: Require a script not found in @INC array
by pernod (Chaplain) on Oct 07, 2004 at 08:35 UTC

    Try FindBin, it will create the absolute path to the directory where the script is run, and make it accessible in the variable $FindBin::Bin. Eg:

    #! /usr/bin/perl use FindBin; use lib "$FindBin::Bin/../moduledir"; use My::Module; my $lister = My::Module->new(); . . .

    Where moduledir is where I place my own code (big surprise :). This solved similar problems for me.

    Hope this helps!

    pernod
    --
    Mischief. Mayhem. Soap.

      I couldn't make this work, due to my own inadequacies as a Perl programmer, but it did get me to thinking. I went to the CGI Resource site and downloaded a freeware script called ServerCheck by Virtual Solutions. It showed me that the path I had been using was incorrect. Whether it was reported wrong, or I simply wrote it down wrong, is unknown, but as soon as I corrected it in Config.sys, the script worked. Thanks to everyone for their suggestions. You've saved my scalp once again. I was about to start pulling my hair out. :)
Re: Require a script not found in @INC array
by shemp (Deacon) on Oct 07, 2004 at 16:37 UTC
    It could also be a problem with file ownership / permissions. If the user that is running the web server, and thus the CGI's doesnt have permission to read the require'd libraries, you will get that exact error. For instance, i ran a trivial test where i changed a librarys owner and group to root, with a 600 permission, then tried to require it in another script, and got the cant locate library in @INC error. Heres what i mean:
    ls -l test_lib.pl -rw------- 1 root root 62 Oct 7 11:30 test_lib.pl # and heres the script that includes it: #!/usr/bin/perl require 'test_lib.pl';
    Yep, thats the whole thing.

    So you may want to look at permissions, ownership of your required files.