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

aks*_*aks 49 directory perl module

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

/home/mutew/src/prod/pskill       <-- Perl script
/home/mutew/src/prod/Process.pm   <-- Package to handle process descriptions
Run Code Online (Sandbox Code Playgroud)

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

use lib '/home/mutew/src/prod';
Run Code Online (Sandbox Code Playgroud)

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


编辑

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

小智 57

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

use File::Basename;
use lib dirname (__FILE__);
use SomeModuleLocatedInTheSameDirectoryAsThisPerlScriptOrModule;
Run Code Online (Sandbox Code Playgroud)

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

要拥有相对于此Perl文件位置的任何其他路径,请执行类似的操作

use File::Basename;
use lib dirname (__FILE__) . "/MyModules";
Run Code Online (Sandbox Code Playgroud)

  • 我非常喜欢这种方法 - 我只需要使用`使用Cwd qw(abs_path); 使用lib dirname(abs_path(__ FILE __));`使脚本可以通过符号链接调用.干杯! (7认同)
  • 这是通过搜索Google几分钟对我唯一有效的答案。它足够简单,足够清晰并且对新手友好。 (2认同)

小智 52

最简单的方法我发现它使用FindBin模块.像这样:

use FindBin;
use lib $FindBin::Bin;
Run Code Online (Sandbox Code Playgroud)

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

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

use Cwd qw(abs_path);
use FindBin;
use lib abs_path("$FindBin::Bin/../lib");
Run Code Online (Sandbox Code Playgroud)

abs_path调用是为了让@INC包含/ lib,而不是/ bin /../ lib - 它只是一个小小的改动,但更容易阅读错误消息.

  • 不要忘记abs_path在污点模式下返回污染结果.你必须使用`use lib(abs_path("$ FindBin :: Bin /../ lib")= ~m {^(/.*)})[0];`或者只使用`use lib"$ FindBin :: Bin /../ lib";`因为没有理由去封锁路径. (4认同)

bri*_*foy 13

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


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

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

PERLLIB环境变量

$ export PERLLIB=/path/to/my/dir
$ perl program.pl
Run Code Online (Sandbox Code Playgroud)

PERL5LIB环境变量

$ export PERL5LIB=/path/to/my/dir
$ perl program.pl
Run Code Online (Sandbox Code Playgroud)

perl -Idir命令行标志

$ perl -I/path/to/my/dir program.pl
Run Code Online (Sandbox Code Playgroud)

使用lib pragma:

use lib "$ENV{HOME}/myown_perllib";
Run Code Online (Sandbox Code Playgroud)

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


Rob*_*ert 8

除了已经提出的解决方案之外:

\n\n
    \n
  1. 使用 FindBin/lib
  2. \n
  3. Perl 常见问题解答 8如何在运行时将目录添加到我的包含路径 (@INC)?
  4. \n
\n\n

我在部署模块之前(在 /usr/local/lib/site_perl/ 或 @INC 中的其他位置)开发/测试模块时使用的“最简单的方法”(\xe2\x84\xa2)是\n修改@INC在加载模块之前如下:

\n\n
#!/usr/bin/perl\nuse strict;\nuse warnings;\n# Modify @INC prior to module loading.\nBEGIN { unshift @INC, \'.\'; }\nuse YourModuleInCWD;\n
Run Code Online (Sandbox Code Playgroud)\n\n

将当前工作目录添加到@INC? - PerlMonks

\n