开发者

How do I load libraries relative to the script location in Perl?

How can you get current script directory in Perl?

This has to work even if the script is imported from another script (require).

This is not the current 开发者_如何学Godirectory

Example:

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

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

The script foo.pl could be executed in any ways and from any directory, like perl /aaa/foo.pl, or ./foo.pl.


What people usually do is

use FindBin '$Bin';

and then use $Bin as the base-directory of the running script. However, this won't work if you do things like

do '/some/other/file.pl';

and then expect $Bin to contain /some/other/ within that. I'm sure someone thought of something incredibly clever to work this around and you'll find it on CPAN somewhere, but a better approach might be to not include a program within a program, but to use Perl's wonderful ways of code-reuse that are much nicer than do and similar constructs. Modules, for example.

Those generally shouldn't care about what directory they were loaded from. If they really need to operate on some path, you can just pass that path to them.


See Dir::Self CPAN module. This adds pseudo-constant __DIR__ to compliment __FILE__ & __LINE__.

use Dir::Self;

use lib __DIR__ . '/lib'; 


I use this snippet very often:

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

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

This will give you the real path to the directory containing the currently running script. "real path" means all symlinks, "." and ".." resolved.


Sorry for the other 4 responses but none of them worked, here is a solution that really works.

In below example that adds the lib directory to include path the $dirname will contain the path to the current script. This will work even if this script is included using require from another directory.

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


From perlfaq8's answer to How do I add the directory my program lives in to the module/library search path?


(contributed by brian d foy)

If you know the directory already, you can add it to @INC as you would for any other directory. You might if you know the directory at compile time:

use lib $directory;

The trick in this task is to find the directory. Before your script does anything else (such as a chdir), you can get the current working directory with the Cwd module, which comes with Perl:

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

use lib $directory;

You can do a similar thing with the value of $0, which holds the script name. That might hold a relative path, but rel2abs can turn it into an absolute path. Once you have the

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

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

use lib $directory;

The FindBin module, which comes with Perl, might work. It finds the directory of the currently running script and puts it in $Bin, which you can then use to construct the right library path:

use FindBin qw($Bin);

You can also use local::lib to do much of the same thing. Install modules using local::lib's settings then use the module in your program:

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

See the local::lib documentation for more details.


Let's say you're looking for script.pl. You may be running it, or you may have included it. You don't know. So it either lies in the %INC table in the first case or as $PROGRAM_NAME (aka $0) in the second.

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";

Link to File::Basename, File::Spec, and List::Util

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜