Can't locate *** in #INC - perl

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.

Related

Perl throws "Can't locate Config/YAML.pm in #INC"

I'm getting Can't locate Config/YAML.pm in #INC (you may need to install the Config::YAML module) while running a perl script.
Can't locate Config/YAML.pm in #INC (you may need to install the
Config::YAML module) (#INC contains: /etc/perl
/usr/local/lib/perl/5.18.2 /usr/local/share/perl/5.18.2 /usr/lib/perl5
/usr/share/perl5 /usr/lib/perl/5.18 /usr/share/perl/5.18
/usr/local/lib/site_perl .) at myperlscript line 8. BEGIN
failed--compilation aborted at myperlscript line 8.
Line 8 of the script shows use Config::YAML;.
I'm using Ubuntu and have installed the libdata-yaml-perl and libyaml-perl packages, but still am getting the same error. What else is needed?
Config::YAML requires a different package. Install the libconfig-yaml-perl package and the problem will be fixed.
As the error says, something is missing in #INC. If you do have the module installed (perldoc -l YAML::Tiny for example) it might be installed in a location that is not added to #INC (see How is Perl's #INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?) for how it's constructed).
That means that there could be something wrong with environment variables: if for example PERL5LIB is not set (or not set correctly), it could also cause this error.
For example, if Perl is installed in /home/myusername/perl5, setting PERL5LIB="/home/myusername/perl5/lib/perl5" can fix this (e.g. in your ~/.profile, don't forget to log out and in).
For reference, here is what my Perl installation had autogenerated:
PATH="/home/myusername/perl5/bin${PATH:+:${PATH}}"; export PATH;
PERL5LIB="/home/myusername/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
PERL_LOCAL_LIB_ROOT="/home/myusername/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
PERL_MB_OPT="--install_base \"/home/myusername/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=/home/myusername/perl5"; export PERL_MM_OPT;

Can I move perl modules without breaking the system?

I have the exact problem described here:
Perl can't find module when run from cron.daily except that my problem applies to a perl script running from crontab.
In my case the error message is:
May 24 22:12:02 trackcam3 test_cron: Can't locate Image/Grab.pm in #INC (you may need to install the Image::Grab module) (#INC contains: /etc/perl /usr/local/lib/arm-linux-gnueabihf/perl/5.24.1 /usr/local/share/perl/5.24.1 /usr/lib/arm-linux-gnueabihf/perl5/5.24 /usr/share/perl5 /usr/lib/arm-linux-gnueabihf/perl/5.24 /usr/share/perl/5.24 /usr/local/lib/site_perl /usr/lib/arm-linux-gnueabihf/perl-base) at /home/darren/upload_image.pl line 33, <DATA> line 1.
May 24 22:12:02 trackcam3 test_cron: BEGIN failed--compilation aborted at /home/darren/upload_image.pl line 33, <DATA> line 1.
The solutions at the link all add something to the path. I would like to know if I can move or copy the modules to somewhere they can be found when perl scripts from crontab.
As part of troubleshooting I have already loaded cron with the same PATH as I have from the terminal but that is not enough to allow the perl module to be found.
The missing module is in ~/perl5/lib/perl5 which is not in #INC
The same perl script call modules that are located at
/usr/lib/arm-linux-gnueabihf/perl5/5.24/Image/Magick
Should it be somewhere else? At present /usr/lib/perl5 is empty. The OP in the link asked the same question in the link but didn't receive an answer.
Try:
use lib glob( '~/perl5/lib/perl5' );
use Image::Grab;
The use lib must come before many use module.
Follow the link in the following comment by #haukex to arrive at a full explanation.

Can't locate XML/LibXML.pm in #INC

I am trying to run script which uses XML/LibXML package.
But, XML/LibXML package is already installed. I ran following command:
perl -MXML::LibXML -e 1. it did not give any output, that means this package is installed.
when i ran my script. Following error occured.
Can't locate XML/LibXML.pm in #INC (#INC contains:
/usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl
/usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl
/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8
.). BEGIN failed--compilation aborted.
One more point to note is there is no directory "5.8.8" under /usr/lib64/perl5/site_perl/
Please suggest to overcome this issue.
There are three possibilities:
You have two installs of perl and you script is using the "wrong" one.
Either install XML::LibXML using the perl used by the script, or replace the script's shebang (#!) line with the output of the following:
perl -MXML::LibXML -le'print "#!".$^X'
Differences in the environment.
If XML::LibXML was installed in a nonstandard directory, it could be that PERL5LIB was used to communicate this to perl when you executed your test, but not when you run the script.
A permission issue.
This isn't very likely.
If the script is run as the same user as your test, it's not a permission issue.
If it is a permission issue, make sure the library directory is accessible to the user executing the script.

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';

Perl, Can't locate Packet/UDP/Syslog.pm in #INC | custom modules

Anybody please can spot a mistake here? I do have one perl script and 3 custom perl modules. I specified location of the modules using export, also using -I, also inside the script using:
use lib '/var/pwn/syslog-generator/perl-modules/';
but script still fails with common error:
Can't locate Packet/UDP/Syslog.pm in #INC (#INC contains: /var/pwn/syslog-generator/perl-modules/ ./ /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 raw-syslog.pl line 5.
BEGIN failed--compilation aborted at raw-syslog.pl line 5.
modules are located here:
ls /var/pwn/syslog-generator/perl-modules
Packet.pm Syslog.pm UDP.pm
perl -V
Compiled at Sep 30 2013 03:45:34
%ENV:
PERL5LIB=":/var/pwn/syslog-generator/perl-modules/"
#INC:
/var/pwn/syslog-generator/perl-modules/
/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
And my perl script starts like this:
#!/usr/bin/perl
use strict; use warnings;
use lib './';
use lib '/var/pwn/syslog-generator/perl-modules/';
use Packet::UDP::Syslog;
use POSIX qw/strftime/;
I also tryed to start the script with -Idirectory [specify #INC/#include directory], but:
perl -I /var/pwn/syslog-generator/perl-modules raw-syslog.pl
Can't locate Packet/UDP/Syslog.pm in #INC (#INC contains: /var/pwn/syslog-generator/perl-modules/ ./ /var/pwn/syslog-generator/perl-modules /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 raw-syslog.pl line 5.
BEGIN failed--compilation aborted at raw-syslog.pl line 5.
again, no luck. Something obvious I am missing?
Thank you
Do you have 3 modules in 3 files called Packet.pm, Syslog.pm, and UDP.pm?
Do they have package Packet; , package Syslog; and package UDP; respectively at their top?
If so, you need to load each one of them separately using
use Packet;
use Syslog;
use UDP;
On the other hand, if you have one file in Packet/Syslog/UDP.pm then it has to have
package Packet::Syslog::UDP; at the top and you'd load it using
use Packet::Syslog::UDP;
Oh, and BTW, if this is up to you, I'd strongly recommend using a company or project specific module name-space. So instead of 'Packet.pm' I'd create a file called 'Company/Packet.pm' which would have package Company::Packet; at the top and I'd load it with use Company::Packet; Otherwise you'll easily bump into modules with the same name.
Some articles that might shed more light on the subject:
How to create a Perl Module for code reuse?
Packages, modules, distributions, and namespaces in Perl
(disclaimer: articles written by myself)
When you use Packet::UDP::Syslog, Perl will mangle that name to the path Packet/UDP/Syslog.pm. It will then loop through the #INC directories and look for matches:
/var/pwn/syslog-generator/perl-modules/Packet/UDP/Syslog.pm
/etc/perl/Packet/UDP/Syslog.pm
/usr/local/lib/perl/5.14.2/Packet/UDP/Syslog.pm
/usr/local/share/perl/5.14.2/Packet/UDP/Syslog.pm
/usr/lib/perl5/Packet/UDP/Syslog.pm
/usr/share/perl5/Packet/UDP/Syslog.pm
/usr/lib/perl/5.14/Packet/UDP/Syslog.pm
/usr/share/perl/5.14/Packet/UDP/Syslog.pm
/usr/local/lib/site_perl/Packet/UDP/Syslog.pm
./Packet/UDP/Syslog.pm
If none of those files exists, the module hasn't been found. However, you only have these files:
/var/pwn/syslog-generator/perl-modules/Packet.pm
/var/pwn/syslog-generator/perl-modules/Syslog.pm
/var/pwn/syslog-generator/perl-modules/UDP.pm
That's not correct because the file system hierarchy is relevant when resolving namespaces. I suggest you properly install your module rather than copying files into a directory. You can use cpan or cpanm to install the module, and can use local::lib to install to a custom module location.