如何相对于Perl中的脚本位置加载库?

时间:2010-10-01 16:51:46

标签: perl

如何在Perl中获取当前的脚本目录?

即使从另一个脚本(require)导入脚本,这也必须正常工作。

这不是当前目录

示例:

#/aaa/foo.pl
require "../bbb/foo.pl"

#/bbb/bar.pl
# I want to obtain my directory (`/bbb/`)
print($mydir)

脚本foo.pl可以通过任何方式执行,也可以从任何目录执行,例如perl /aaa/foo.pl./foo.pl

6 个答案:

答案 0 :(得分:4)

人们通常做的是

use FindBin '$Bin';

然后使用$Bin作为正在运行的脚本的基本目录。但是,如果您执行

之类的操作,则无法执行此操作
do '/some/other/file.pl';

然后期望$Bin在其中包含/some/other/。我确信有人想到了一些非常聪明的东西,你可以在CPAN的某个地方找到它,但更好的方法可能是不在程序中包含一个程序,而是使用Perl的奇妙的代码重用方式。比do和类似的结构好得多。例如,模块。

那些人通常不应该关心他们从哪个目录加载。如果他们确实需要在某个路径上运行,您可以将该路径传递给他们。

答案 1 :(得分:2)

请参阅Dir::Self CPAN模块。这会将伪常量 __DIR__添加到赞美__FILE__& __LINE__

use Dir::Self;

use lib __DIR__ . '/lib'; 

答案 2 :(得分:1)

我经常使用此代码段:

   use Cwd qw(realpath);
   use File::Basename;

   my $cwd = dirname(realpath($0));

这将为您提供包含当前正在运行的脚本的目录的真实路径。 “真实路径”表示所有符号链接,“。”并且“......”解决了。

答案 3 :(得分:1)

很抱歉其他4个回复,但没有一个有效,这是一个真正有效的解决方案。

在下面添加lib目录以包含路径的示例中,$dirname将包含当前脚本的路径。即使使用另一个目录中的require包含此脚本,这也会有效。

BEGIN {
   use File::Spec;
   use File::Basename;
   $dirname = dirname(File::Spec->rel2abs( __FILE__ )) . "/lib/";
}
use lib $dirname;

答案 4 :(得分:1)

perlfaq8回答How do I add the directory my program lives in to the module/library search path?


(由brian d foy提供)

如果您已经知道该目录,则可以像在任何其他目录中一样将其添加到@INC。如果您在编译时知道目录,则可能是:

use lib $directory;

此任务的技巧是找到目录。在脚本执行任何其他操作(例如chdir)之前,您可以使用Perl附带的Cwd模块获取当前工作目录:

BEGIN {
    use Cwd;
    our $directory = cwd;
    }

use lib $directory;

您可以使用$ 0的值执行类似的操作,该值保存脚本名称。这可能会保持相对路径,但rel2abs可以将其转换为绝对路径。一旦你有了

BEGIN {
    use File::Spec::Functions qw(rel2abs);
    use File::Basename qw(dirname);

    my $path   = rel2abs( $0 );
    our $directory = dirname( $path );
    }

use lib $directory;

Perl附带的FindBin模块可能有效。它找到当前运行的脚本的目录并将其放入$ Bin,然后您可以使用它来构建正确的库路径:

use FindBin qw($Bin);

你也可以使用local :: lib做同样的事情。使用local :: lib的设置安装模块,然后使用程序中的模块:

 use local::lib; # sets up a local lib at ~/perl5

有关详细信息,请参阅local :: lib文档。

答案 5 :(得分:0)

假设您正在寻找script.pl。您可能正在运行它,或者您可能已将其包含在内。你不知道。所以它可以位于第一种情况下的%INC表中,也可以位于第二种情况下的$PROGRAM_NAME(又名$0)中。

use strict;
use warnings;
use English qw<$PROGRAM_NAME>;    
use File::Basename qw<dirname>;
use File::Spec;
use List::Util qw<first>;

# Here we get the first entry that ends with 'script.pl'
my $key  = first { defined && m/\bscript\.pl$/ } keys %INC, $PROGRAM_NAME;
die "Could not find script.pl!" unless $key;
# Here we get the absolute path of the indicated path.
print File::Spec->rel2abs( dirname( $INC{ $key } || $key )), "\n";

指向File::BasenameFile::SpecList::Util

的链接