perl library path
This answer assumes that the module is in fact installed, but not in a place that perl
is looking for.
Generally, the Perl module Statistics::Distributions
will be contained in a file called Statistics/Distributions.pm
. On Linux and similar systems, one can search for these files quickly with the locate
command:
locate Statistics/Distributions.pm
If it is installed, locate
will spit out a line similar to
/opt/my_perl/lib/Statistics/Distributions.pm
You can then instruct the perl
interpreter to look in this path, too, in various ways. One is to define the environment variable PERL5LIB
, i.e. from bash
:
prompt> PERL5LIB=/opt/my_perl/lib/ ./myscript.pl
Or you can use the perl -I
switch:
prompt> perl -I/opt/my_perl/lib/ ./myscript.pl
Or you can modify the script to use lib
; there is more than one way to do it ;-)
How can I find out where a Perl module is installed?
Note: This solution proposes use of a (self-authored) utility that you must download. While it offers what I believe to be helpful features, installing a third-party solution first is not an option for everyone.
I've created whichpm
, a cross-platform CLI (Linux, macOS, Window) that locates installed Perl modules by module (package) name, and optionally reports information about them, including detection of accidental duplicates.
Examples
# Locate the Data::Dumper module.
$ whichpm Data::Dumper
/usr/lib/perl/5.18/Data/Dumper.pm
# Locate the Data::Dumper module, and also print
# version information and core-module status.
$ whichpm -v Data::Dumper
Data::Dumper 2.145 core>=5.005 /usr/lib/perl/5.18/Data/Dumper.pm
# Locate the Data::Dumper module and open it in your system's default text
# editor.
$ whichpm -e Data::Dumper
# Look for accidental duplicates of the Foo::Bar module.
# Normally, only 1 path should be returned.
$ whichpm -a Foo::Bar
/usr/lib/perl/5.18/Foo/Bar.pm
./Foo/Bar.pm
# Print the paths of all installed modules.
$ whichpm -a
Installation
Prerequisites: Linux, macOS, or Windows, with Perl v5.4.50 or higher installed.
Installation from the npm registry
With Node.js or io.js installed, install the package as follows:
[sudo] npm install whichpm -g
Manual installation (macOS and Linux)
- Download the CLI as
whichpm
. - Make it executable with
chmod +x whichpm
. - Move it or symlink it to a folder in your
$PATH
, such as/usr/local/bin
(OSX) or/usr/bin
(Linux).
Perl library path/s
print the contents of the @INC
variable:
perl -e 'print "@INC\n";'
@INC
contains all the paths that Perl will search to find a module.
How do I include a Perl module that's in a different directory?
EDIT: Putting the right solution first, originally from this question. It's the only one that searches relative to the module directory:
use FindBin; # locate this script
use lib "$FindBin::Bin/.."; # use the parent directory
use yourlib;
There's many other ways that search for libraries relative to the current directory. You can invoke perl with the -I argument, passing the directory of the other module:
perl -I.. yourscript.pl
You can include a line near the top of your perl script:
use lib '..';
You can modify the environment variable PERL5LIB before you run the script:
export PERL5LIB=$PERL5LIB:..
The push(@INC) strategy can also work, but it has to be wrapped in BEGIN{} to make sure that the push is run before the module search:
BEGIN {push @INC, '..'}
use yourlib;
Calling a Perl Module which is Installed in different path/directory
$RealBin
is the directory in which the script is located. ($Bin
is a broken version of the same thing.)
If there's no relationship between the directory in which the script is located and the directory in which a module is located, it doesn't make sense to use $RealBin
. In fact, it usually makes more sense to use the PERL5LIB
env var than use lib
in such cases.
On the other hand, if the script was located in /path/to/bin
, it might make sense to use a path relative to $RealBin
.
use lib # In /path/to/bin/script,
"$RealBin/../lib1", # This is /path/to/bin/../lib1, or /path/to/lib1
"$RealBin/../lib2", # This is /path/to/bin/../lib2, or /path/to/lib2
"$RealBin/../lib3"; # This is /path/to/bin/../lib3, or /path/to/lib3
$RealBin
is usually used when the script and modules are packaged together (part of the same project). Same for use lib
, really.
perl - package name: Can I use path from root?
The module namespace is relative to @INC
directories only. These are by default set up according to where Perl was installed, with privlib (core modules installed with Perl), sitelib (modules installed by a CPAN client), and vendorlib (modules installed by a vendor package manager), and architecture-specific versions of each of these. Additional @INC
directories may be added by local::lib, and before Perl 5.26 @INC
also included .
(the current working directory), but this was a bad idea.
When you invoke use
or require
on a bareword package name, it does the translation you described (convert ::
to path separator and append .pm
), and then appends it to each directory in @INC
until it finds a file. (It also checks for .pmc
but this is rarely relevant.) The package statement inside the file is expected to match the module path used to look it up for the import component of use
.
You can modify @INC
manually, but it is best to do it with one of the following mechanisms, so that architecture-specific and version-specific subdirectories will be respected if present.
- lib -
use lib '/path/to/lib';
- -I -
perl -I/path/to/lib ...
- PERL5LIB -
env PERL5LIB=/path/to/lib perl ...
These options should only be used to insert absolute paths into @INC
, since relative paths will have the same vulnerability as .
used to, in that they may mean something different when the current directory is changed. To add a path relative to the script wherever it may be, lib::relative can be installed to simplify the process, or its documentation describes equivalent functionality using core modules.
use lib::relative '../lib';
Once you have added your custom location(s) to @INC
, that directory will be searched first for any further use
calls.
use Foo::Bar; # now checks /path/to/lib/Foo/Bar.pm first
# which should contain package Foo::Bar
Adding a path to @INC but not within the Perl script
From what I can gather of your description, the PERL5LIB
seems to be a good solution.
I don't know what you mean by "PERL5LIB
checks the modules in the directory but not recursive", but PERL5LIB
is a shell variable, normally set in your shell configuration files (while this can also be done dynamically), to a list of directories. From Environment (perlrun), the PERL5LIB
is
A list of directories in which to look for Perl library files before looking in the standard library and the current directory. [...]
So you can set it to a suitable list of directories that covers all that is needed.
Make sure that it is an environment variable, by using export
in [ba]sh
export PERL5LIB="/path/to/dir1:/other/path/dir2:$HOME/inhome/dir3"
where the quotes are there in case there are spaces in directory names. This line is normally entered in the file ~/.bashrc
Or, use setenv
if in [t]csh
, with a following line to add to ~/.tcshrc
setenv PERL5LIB "/path/to/dir1:/other/path/dir2:$HOME/inhome/dir3"
Related Topics
On Building Docker Image Level=Error Msg="Can't Close Tar Writer: Io: Read/Write on Closed Pipe"
In Shell, Split a Portion of a String with Dot as Delimiter
Gnu Octave, Round a Number to Units Precision
How to Edit a Symlink with a Text Editor
How to Check If The Sed Command Replaced Some String
Analog of Com Programming in Linux/Unix
$${Home} or ${Home} in Makefile
How to Avoid Having Version Numbers in .So File Name
Differences Between Sponge and Tee
What Does '#Pragma Gcc Optimize ("O3")' Mean
Autoconf Check for Program and Fail If Not Found
What Does It Mean to Break User Space
Find Out The Time Since Unix Epoch for a Certain Date Time
Diff Files Comparing Only First N Characters of Each Line
Cross-Compilation to X86_64-Unknown-Linux-Gnu Fails on MAC Osx
Get .Net Core Dll Version on Linux
Chmod a Freshly Mounted External Drive to Set Up Writing Access