How do I set Perl's #INC for a CGI script? - perl

I have the following, simplest Perl CGI script:
use strict;
use warnings;
use CGI();
use CGI::Carp qw(fatalsToBrowser);
use Template;
print CGI::header();
foreach(#INC) {
print "$_\n";
}
When called (http://[..]/cgi-bin/p.cgi) I am given the following error:
Can't locate Template.pm in #INC (#INC contains: /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8 .) at /home/pistacchio/webapps/htdocs/cgi-bin/p.cgi line 8.
BEGIN failed--compilation aborted at /home/pistacchio/webapps/htdocs/cgi-bin/p.cgi line 8.
I made sure that Template is installed and indeed when running this program from shell it works (loads Template) and outputs:
Content-Type: text/html; charset=ISO-8859-1
/home/pistacchio/lib/perl5
/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
/home/pistacchio/lib/perl5/lib
/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.8
/usr/lib/perl5/site_perl
/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.8
/usr/lib/perl5/vendor_perl
/usr/lib/perl5/5.8.8/i386-linux-thread-multi
/usr/lib/perl5/5.8.8
Template is installed in /home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
[pistacchio#web118 i386-linux-thread-multi]$ pwd
/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
[pistacchio#web118 i386-linux-thread-multi]$ ls
auto perllocal.pod Template Template.pm
This directory is correctly listed in env and, as previously posted, in #INC. In #INC it is shown twice, so I even tried to pop it out before calling use Template, but without result. From env:
[pistacchio#web118 i386-linux-thread-multi]$ env
[..]
PERL5LIB=/home/pistacchio/lib/perl5:/home/pistacchio/lib/perl5/lib:/home/pistacchio/lib/perl5/lib/i386-linux-thread-multi
[..]
Removing use Template gets rid of the problem.

The webserver doesn't run as your user, so its environment isn't your user environment. You can set that up in a variety of ways depending on your webserver. In Apache, you can use the SetEnv directive:
SetEnv PERL5LIB /path/to/your/libs
That then applies to everything under it. If you have it in a .htaccess file, for instance, it applies to everything under that directory.
If you can't do something like that, you're stuck setting the value of #INC in each script yourself with the lib pragma.

I would suggest adding the following to your CGI
use lib "/home/pistacchio/lib/" ;
The PERL5LIB env variable is presumably not available to CGI programs.
Edit What I meant, any value you have set in PERL5LIB from a shell will not be available.

Related

Cannot use already installed Perl Module on cPanel

I have already successfully installed the Perl module Crypt::CBC on cPanel.
But when adding the line "use Crypt::CBC;" I am getting the error:
Can't locate Crypt/CBC.pm in #INC (#INC contains: /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8 .) at sagepay.pl line 128.
BEGIN failed--compilation aborted at sagepay.pl line 128.
Did I miss something? Quite new to Perl modules installation.
check the value of #INC by running this using your web server:
perl -e 'print "Content-type: text/plain\r\n\r\n" . join(":",#INC);'
#INC is where perl looks for modules. Perhaps they got installed in the wrong location.
You can add new locations with perl's -I option (see "man perlrun" for details)
I suspect that you may have added the module to cPanel instead of to the system Perl, for which you need to use WHM. Take a look at these instructions and follow the directions headed Install modules to the system Perl binary
Thanks everyone! Just a wrong path, I used this and it now works:
use lib '/data01/c1501978/perl/usr/lib/perl5';

Can't locate *** in #INC

I install perl modules in ~/.local/perl5. Here's part of ~/.bashrc:
export PERL_LOCAL_LIB_ROOT="$HOME/.local/perl5";
export PERL_MB_OPT="--install_base $HOME/.local/perl5";
export PERL_MM_OPT="INSTALL_BASE=$HOME/.local/perl5";
export PERL5LIB="$HOME/.local/perl5/lib/perl5:$PERL5LIB";
export PATH="$HOME/.local/perl5/bin:$PATH";
I've installed CSS::Inliner with
$ cpan
cpan[1]> install CSS::Inliner
and I have Inliner.pm at:
~/.local/perl5/lib/perl5/CSS/Inliner.pm
But when I use it -- perl can't find it:
perl -e 'use Inliner'
gives:
Can't locate Inliner.pm in #INC (#INC contains:
/home/boris/.local/perl5/lib/perl5/x86_64-linux-gnu-thread-multi
/home/boris/.local/perl5/lib/perl5 /etc/perl
/usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5
/usr/share/perl5 /usr/lib/perl/5.14 /usr/share/perl/5.14
/usr/local/lib/site_perl .) at -e line 1. BEGIN failed--compilation
aborted at -e line 1.
why can't perl find the module?
Edit:
I'm trying to reproduce minimal working example given in documentation to CSS-Inliner:
use Inliner;
my $inliner = new Inliner();
$inliner->read_file({filename => 'myfile.html'});
print $inliner->inlinify();
If I use Inliner -- perl can't find it. If I
#!/usr/bin/perl
use CSS::Inliner;
my $inliner = new Inliner();
$inliner->read_file({filename => 'test.html'});
print $inliner->inlinify();
perl says
Can't locate object method "new" via package "Inliner"
(perhaps you forgot to load "Inliner"?) at ./1.perl line 5.
Edit 2:
Here's a minimal working example of CSS-Inliner:
#!/usr/bin/perl
use CSS::Inliner;
my $inliner = CSS::Inliner->new;
$inliner->read_file({filename => 'test.html'});
print $inliner->inlinify();
You should use the full module name in use and full class name when calling class methods:
use CSS::Inliner;
my $inliner = CSS::Inliner->new;
This could happen when you are not careful in installing modules. Once I simply copied the foo.pm into the official /usr/lib/perl5/site_perl directory. The foo.pm could be modules developed locally or third party. I did not pay attention to the umask. Files installed there are not readable by the world. When I use the module I will get the message saying: Cannot locate foo.pm in #INC(#INC contains /usr/lib/perl5/site_perl ....). Gee it is clearly there! Took me a while to check the file permission. Hope this may save some time for others who install their own modules. In make file you should use install -m 644 to make sure the installed module has read permission for others.

Custom Perl Modules on Apache2 Server

Currently I am trying to use a bunch of custom perl modules, test.pm as one of them, within my Perl program with a WebUI. I am running it on a Windows 7 machine with Apache2 installed. When I run the program in cmd prompt by using perl test.pl, the program runs fine. However running it on Apache gives me this error.
[Wed Jun 13 16:23:32 2012] [error] [client 127.0.0.1] Can't locate test.pm in #INC (#INC contains: C:/Perl/lib C:/Perl/site/lib .) at C:/www/hello2.pl line 7.\r, referer: http://localhost/ui_test.htm
[Wed Jun 13 16:23:32 2012] [error] [client 127.0.0.1] BEGIN failed--compilation aborted at C:/www/hello2.pl line 7.\r, referer: http://localhost/ui_test.htm
I have used:
foreach $key (sort keys(%ENV)) {
print "$key = $ENV{$key}<p> \n";
}
and under the path variable, I do see the folder of where all the modules are located. Is there somewhere else I should use to add to the Perl Path?
In addition adding use lib "C:\testpm\"; to my code only changes the #INC to
(#INC contains: C:\testpm\ C:/Perl/lib C:/Perl/site/lib .)
Is there something additional you need to do to add paths to run custom perl modules on an apache server?
Solution Based On Answer:
I found this to work the best. Within my httpd-perl.conf file, I added these lines:
<IfModule env_module>
SetEnv PERL5LIB "C:\testpm;C:\testpm1;"
</IfModule>
(extended out with C:\testpm1 to show people with similar questions how to add even more module folders.)
The PATH environment variable has no bearing on where perl will load modules from, that is #INC. You said your path is in #INC, but in the error message you show, it is not.
Can't locate test.pm in #INC (#INC contains: C:/Perl/lib C:/Perl/site/lib .) at
You should call use lib during server startup. See http://perl.apache.org/docs/2.0/user/handlers/server.html#Startup_File.
Also, try removing the trailing slash, eg use lib 'C:\testpm'.
use lib is good if you can add in setup file otherwise you will have to add it in every single perl script file.Rather than doing this, you can use PERL5LIB environment variable.
#INC in perl doesn't take value of PATH environment variable rather it can take from PERL5LIB environment variable.
You can add SetEnv PERL5LIB path_to_modules_directory directive in your apache configuration.Your perl script will add this path at front of original #INC value while executing your perl script.

Can't locate File/Glob.pm in #INC (#INC contains: D:/tools/lib .) at directory.pl line 2

I get this error when running my perl code
Can't locate File/Glob.pm in #INC (#INC contains: D:/tools/lib .) at directory.pl line 2.
line 2: #files=<*>;
When i run the command, I get,
Y:\perl\perl>perldoc -l File::Glob
D:\tools\lib\perl\510\File\Glob.pm
So I think the File::Glob module is installed?
#INC should be set correctly upon installation of Perl. When it doesn't match your configuration, you seem to have messed up something.
However, if the current value of #INC doesn't fit your needs, you have various options:
Add D:\tools\lib\perl\510\ to the
environment variable PERL5LIB (or PERLLIB if this doesn't work)
Specify #INC on startup:
perl -I D:\tools\lib\perl\510\
Instead of writing use libname, you can write use path/to/libname
Using a BEGIN block before the use statements:
BEGIN {
push #INC,"D:\tools\lib\perl\510\";
}
See also http://perldoc.perl.org/perlvar.html for a short introduction.

Why I can't run perl from Textmate?

#!/usr/bin/perl -w
use WWW::Mechanize;
print $WWW::Mechanize::VERSION."\n";
1) run from Textmate :
Can't locate WWW/Mechanize.pm in #INC (#INC contains:
/Applications/TextMate.app/Contents/SharedSupport/Bundles/Perl.tmbundle/Support
/Library/Perl/Updates/5.10.0
/System/Library/Perl/5.10.0/darwin-thread-multi-2level
/System/Library/Perl/5.10.0
/Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0
/Network/Library/Perl/5.10.0/darwin-thread-multi-2level
/Network/Library/Perl/5.10.0 /Network/Library/Perl
/System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level
/System/Library/Perl/Extras/5.10.0 .) at
/Users/xxx/Development/test.pl line 2. BEGIN failed--compilation
aborted at /Users/xxx/Development/test.pl line 2.
2) run from terminal:
sh-3.2# perl test.pl<br>
1.64
What should I do?
It appears you installed WWW::Mechanize into a directory that isn't searched by default. Most likely, you have a PERL5LIB or other environment variable that adds that directory to Perl's search path, and for some reason that's not set in the environment TextMate provides.
Try running perl -V from the shell and from TextMate and see what the difference in search paths is. You can also add
print "$INC{'WWW/Mechanize.pm'}\n";
to your test script to find out where it's installed.