我的Perl脚本如何在同一个目录中find它的模块?

我最近编写了一个新的Perl脚本来杀死基于进程名称/用户名的进程,并使用类进行扩展,以便在其他程序中重用进程代码。 我目前的布局是 –

/home/mutew/src/prod/pskill <-- Perl script /home/mutew/src/prod/Process.pm <-- Package to handle process descriptions 

我在$ PATHvariables中添加了〜/ src / prod来从任何地方访问脚本。 在从其目录以外的任何目录运行脚本导致“不能在@INC中定位Process.pm”(这是可以理解的,除了/ usr中的共享目录之外,@INC只包含当前目录 – '')。 我一直在使用的一种解决方法是使用lib指令,

 use lib '/home/mutew/src/prod'; 

但是这是一个重要的可移植性问题。 任何解决scheme,也将允许我导出脚本到其他系统没有和改变?


编辑

  1. 我select“depesz”的答案是正确的,因为它的简单性和核心模块的使用。
  2. brian d foy的回答虽然提出了其他方法来实现(TMTOWTDI),但是他在perlfaq8中的贡献使得这个问题完全是多余的。

我发现它最简单的方法使用FindBin模块。 喜欢这个:

 use FindBin; use lib $FindBin::Bin; 

一般来说,我更喜欢让我的脚本以这样的方式提供,即程序在任何/ bin中,而库在/ lib中

在这些情况下,我使用一个稍微复杂的方法:

 use Cwd qw(abs_path); use FindBin; use lib abs_path("$FindBin::Bin/../lib"); 

abs_path调用是使@INC包含任何/ lib,而不是/ bin /../ lib – 这只是一个小小的改变,但是使得读取错误信息更容易。

我很好奇为什么简单的解决scheme

 use File::Basename; use lib dirname (__FILE__); use SomeModuleLocatedInTheSameDirectoryAsThisPerlScriptOrModule; 

没有出现。 FindBin模块似乎有一些问题,如果该文件不是主要的可执行Perl脚本,但只是一个不可执行的Perl模块。 至less我是这样解释文档中的注释的。 没有真正testing它。

要有任何其他path相对于这个Perl文件的位置,请做类似的事情

 use File::Basename; use lib dirname (__FILE__) . "/MyModules"; 

来自perlfaq8 ,它回答“如何在运行时将目录添加到我的包含path(@INC)?” 。 关于这个问题还有其他几个问题的答案。


如何在运行时将目录添加到包含path(@INC)?

以下是修改包含path的build议方法,包括环境variables,运行时切换和代码内语句:

PERLLIB环境variables

 $ export PERLLIB=/path/to/my/dir $ perl program.pl 

PERL5LIB环境variables

 $ export PERL5LIB=/path/to/my/dir $ perl program.pl 

perl -Idir命令行标志

 $ perl -I/path/to/my/dir program.pl 

使用lib杂注:

 use lib "$ENV{HOME}/myown_perllib"; 

最后一个特别有用,因为它知道机器相关的体系结构。 lib.pm实用程序模块首先包含在5.002版本的Perl中。

看看Par :: Packer ,它会创build一个包含所有脚本依赖项的可执行文件。 它使分发变得容易。 您还可以为您的用户提供可安装在他们的系统上的模块版本。 请参阅Module :: Starter ,了解构build标准CPAN样式分发所需的所有文件的简单方法。

要将相对链接转换为绝对的并添加到@INC,我通常使用ex :: lib。 当然,只有当您打算在计划运行脚本的所有机器上保持脚本和模块的相对位置相同时,这才是有用的。

你可以通过使用-I标志让Perl在任何目录中查找。 这里, -I代表@INC ,它是perl查找模块的path数组。 使用-I将给定的path添加到@INC数组执行此操作。

例如:

 perl -I lib bin/script.pl 

其中lib包含我想要使用的模块。

我知道这适用于perl 5 。 我不确定其他版本。

FindBin :: libs将find所有放置在相对于脚本运行path的合理位置的库。

只是保持简单。 没有必要导入任何图书馆; 只需找出你目前的工作目录:

 use lib "$ENV{PWD}/relativ_path_own_perllib"; 

对于类似的问题,你可以在shell-terminal中只读出一行编程代码来读出环境variables,这些variables给出了你的位置,你的主目录,操作系统的东西等信息,例如:

 perl -e 'map { print; print " : ". $ENV{$_}." \n\r"; } sort keys %ENV ' 

没有必要绑定一些图书馆; 只需使用%ENV-Hash