Reputation: 25347
I recently wrote a new Perl script to kill processes based on either process name / user name and extended it using Classes so that I could reuse the process code in other programs. My current layout is -
/home/mutew/src/prod/pskill <-- Perl script
/home/mutew/src/prod/Process.pm <-- Package to handle process descriptions
I added ~/src/prod in my $PATH variable to access the script from anywhere. On running the script from any directory other than its resident directory leads to a "Can't locate Process.pm in @INC" (which is understandable given that other than the shared directories in /usr, @INC includes only the current directory - '.'). One workaround that I have been using is the use lib directive as so -
use lib '/home/mutew/src/prod';
but this is a major portability issue. Any solutions which will also allow me to export the script to other systems without and changes?
EDIT
Upvotes: 65
Views: 53955
Reputation: 2160
The path can be included in perl script in first line, marked with #!
#!/usr/bin/perl -I.
use anymodule;
Upvotes: 3
Reputation: 511
Besides the already stated solutions:
'The simplest approach' (™) that I use while dev/testing a module prior to deploying it (in /usr/local/lib/site_perl/ or elsewhere in @INC) is to modify @INC before loading the module as follows:
#!/usr/bin/perl
use strict;
use warnings;
# Modify @INC prior to module loading.
BEGIN { unshift @INC, '.'; }
use YourModuleInCWD;
(Add current working directory to @INC? - PerlMonks)
Upvotes: 8
Reputation: 64909
Take a look at Par::Packer. It creates an executable with all of the script's dependencies included. It makes distribution easy. You also could also provide your users a version of your module that can be installed on their systems. See Module::Starter for an easy way to build all of the files required to make a standard CPAN-style distribution.
Upvotes: 3
Reputation: 2028
You can make perl look in any directory by using the -I
flag. Here, -I
stands for @INC
which is the array of paths in which perl looks for modules. Using -I
adds the given path to the @INC
array for this execution.
eg:
perl -I lib bin/script.pl
where lib contains the modules I want to use.
I know that this works for perl 5. I am not at sure about other versions.
Upvotes: 4
Reputation:
The simplest approach I found it to use FindBin module. Like this:
use FindBin;
use lib $FindBin::Bin;
Generally I prefer to have my scripts provided in such a way that programs are in whatever/bin, and libraries are in whatever/lib
In these situations I use a slightly more complicated approach:
use Cwd qw(abs_path);
use FindBin;
use lib abs_path("$FindBin::Bin/../lib");
The abs_path call is to make the @INC contain whatever/lib, and not whatever/bin/../lib - it's just a slight change, but makes reading error messages easier.
Upvotes: 57
Reputation: 11
Just keep it simple. There is no need to import any libraries; just find out your current working directory:
use lib "$ENV{PWD}/relativ_path_own_perllib";
For similar problems, you can read out the environment variable which gives your information about where you are, your home directory, operating system stuff, and so on, with just one row of programming code in the shell-terminal, like:
perl -e 'map { print; print " : ". $ENV{$_}." \n\r"; } sort keys %ENV '
There is no need to bind some libraries; just use the %ENV-Hash
.
Upvotes: 0
Reputation: 11025
FindBin::libs will find all your libs placed at reasonable places relative to the path from where your script is running.
Upvotes: 0
Reputation: 1257
I am curious why the simplistic solution
use File::Basename;
use lib dirname (__FILE__);
use SomeModuleLocatedInTheSameDirectoryAsThisPerlScriptOrModule;
did not come up. The FindBin module seems to have some issues if the file is not the main executable perl script, but simply a non-executable Perl module. At least that's how I interpret the comment in the documentation. Did not really test it.
To have any other path relative to the location of this Perl file, do something like
use File::Basename;
use lib dirname (__FILE__) . "/MyModules";
Upvotes: 84
Reputation: 3562
To convert relative links to absolute and add to @INC, I normally use ex::lib. Of course, this is useful only if you plan to keep the relative locations of the script and the module identical on all machines where you plan to run your script.
Upvotes: 0
Reputation: 132719
From perlfaq8, which answers "How do I add a directory to my include path (@INC) at runtime?". There are several other answers for questions around this issue too.
How do I add a directory to my include path (@INC) at runtime?
Here are the suggested ways of modifying your include path, including environment variables, run-time switches, and in-code statements:
the PERLLIB environment variable
$ export PERLLIB=/path/to/my/dir
$ perl program.pl
the PERL5LIB environment variable
$ export PERL5LIB=/path/to/my/dir
$ perl program.pl
the perl -Idir command line flag
$ perl -I/path/to/my/dir program.pl
the use lib pragma:
use lib "$ENV{HOME}/myown_perllib";
The last 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.
Upvotes: 15