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

时间:2009-04-08 05:17:07

标签: perl module directory

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

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

我在$ PATH变量中添加了〜/ src / prod来从任何地方访问脚本。从其驻留目录以外的任何目录运行脚本会导致“无法在@INC中找到Process.pm”(这是可以理解的,因为除了/ usr中的共享目录之外,@ INC仅包含当前目录 - '')。我一直在使用的一种解决方法是使用lib指令 -

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

但这是一个主要的可移植性问题。任何解决方案还允许我将脚本导出到其他系统而不进行更改?


修改

  1. 由于其简单性和核心模块的使用,我选择'depesz'作为正确答案。
  2. brian d foy的回答虽然提出了其他方法来实现同样的目标(TMTOWTDI),但他在perlfaq8中的贡献使得这个问题绝对多余。

9 个答案:

答案 0 :(得分:54)

我很好奇为什么简单化的解决方案

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

没有出现。如果文件不是主要的可执行文件perl脚本,那么FindBin模块似乎有一些问题,而只是一个不可执行的Perl模块。至少我是如何解释documentation中的评论。没有真正测试它。

要获得相对于此Perl文件位置的任何其他路径,请执行类似

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

答案 1 :(得分:50)

我发现使用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 - 它只是一个小小的改动,但更容易阅读错误消息。

答案 2 :(得分:12)

来自perlfaq8,答案"How do I add a directory to my include path (@INC) at runtime?"。关于这个问题还有其他几个问题的答案。


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

以下是修改包含路径的建议方法,包括环境变量,运行时开关和代码内语句:

PERLLIB环境变量

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

PERL5LIB环境变量

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

perl -Idir命令行标志

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

使用lib pragma:

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

最后一个特别有用,因为它了解机器相关的架构。 lib.pm实用模块最初包含在Perl的5.002版本中。

答案 3 :(得分:3)

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

答案 4 :(得分:2)

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

例如:

perl -I lib bin/script.pl

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

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

除了已经说明的解决方案:

  1. 使用FindBin / lib
  2. Perl常见问题解答8 How do I add a directory to my include path (@INC) at runtime?

我之前在开发/测试模块时使用的“最简单的方法”(™) 部署它(在/ usr / local / lib / site_perl /或@INC的其他地方)是 在加载模块之前修改@INC,如下所示:

#!/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

答案 7 :(得分:-1)

FindBin::libs会发现所有的lib都放在相对于脚本运行路径的合理位置。

答案 8 :(得分:-1)

保持简单。无需导入任何库;找出你当前的工作目录:

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

对于类似的问题,您可以读出环境变量,它提供有关您的位置,主目录,操作系统内容等信息,在shell终端中只有一行编程代码,例如:

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

没有必要绑定一些库;只需使用%ENV-Hash即可。