代码之家  ›  专栏  ›  技术社区  ›  aks

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

  •  46
  • aks  · 技术社区  · 15 年前

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

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

    我在$path变量中添加了~/src/prod,以便从任何地方访问脚本。在从除常驻目录以外的任何目录运行脚本时,会导致“can't locate process.pm in@inc”(这是可以理解的,因为除了/usr中的共享目录,@inc仅包含当前目录-“”。我一直使用的一个解决方法是use lib指令-

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

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


    编辑

    1. 我选择了“depesz”作为正确的答案,因为它的简单性和核心模块的使用。
    2. BrianD-Foy的回答虽然提出了其他实现这一点的方法(tmtowtdi),但他在Perlfaq8中的贡献使这个问题完全多余。
    9 回复  |  直到 6 年前
        1
  •  49
  •   temporary_user_name    7 年前

    我发现使用findbin模块的最简单方法。这样地:

    use FindBin;
    use lib $FindBin::Bin;
    

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

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

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

    abs_path调用的目的是使@inc包含whatever/lib,而不是whatever/bin/../lib——这只是一个小小的更改,但使读取错误消息变得更容易。

        2
  •  52
  •   Andreas Schuh    13 年前

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

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

    没有上来。如果文件不是主要的可执行Perl脚本,而只是一个不可执行的Perl模块,那么findbin模块似乎有一些问题。至少这就是我在 documentation . 没有真正测试过。

    要拥有与此Perl文件位置相关的任何其他路径,请执行如下操作

    use File::Basename;
    use lib dirname (__FILE__) . "/MyModules";
    
        3
  •  12
  •   brian d foy    15 年前

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


    如何在运行时将目录添加到include路径(@inc)中?

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

    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版本中。

        4
  •  3
  •   Community Jaime Torres    6 年前

    看一看 Par::Packer . 它创建一个包含脚本所有依赖项的可执行文件。它使分发变得容易。您还可以向用户提供模块的版本,该版本可以安装在他们的系统上。见 Module::Starter 一个简单的方法来构建所有需要的文件,以进行标准的CPAN样式的分发。

        5
  •  2
  •   Vikas    7 年前

    通过使用 -I 旗帜。在这里, -我 代表 @INC 这是Perl查找模块的路径数组。使用 -我 将给定路径添加到 @ INC 用于此执行的数组。

    如:

    perl -I lib bin/script.pl
    

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

    我知道这对 Perl 5 . 我对其他版本不太确定。

        6
  •  0
  •   Gurunandan Bhat    15 年前

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

        7
  •  0
  •   Robert    6 年前

    除上述解决方案外:

    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 )

        8
  •  -1
  •   Juan A. Navarro    11 年前

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

        9
  •  -1
  •   peak    8 年前

    保持简单。不需要导入任何库;只需查找当前工作目录:

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

    对于类似的问题,您可以使用shell终端中的一行编程代码读取环境变量,该变量提供有关您所在位置、主目录、操作系统资料等的信息,例如:

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

    不需要绑定某些库;只需使用 %ENV-Hash .