В Perl, как я могу получить каталог или путь текущего исполняемого кода? - PullRequest
12 голосов
/ 08 марта 2010

Если я нахожусь в каком-то библиотечном коде, как мне определить путь к файлу кода, который выполняется в настоящее время? Я знаю, как получить путь к perl-файлу top , посмотрев на ARGV, но если я загружаю библиотеку, как эта library может узнать, по какому пути это происходит?

Ответы [ 5 ]

17 голосов
/ 08 марта 2010

Маркер __FILE__ даст вам полный путь, включая имя файла. Вы можете использовать File :: Spec , чтобы разбить его на компоненты:

my ($volume, $directory, $file) = File::Spec->splitpath(__FILE__);
13 голосов
/ 08 марта 2010

Самый простой способ найти имя файла текущего исполняемого файла - с помощью FindBin :

use FindBin;
use File::Spec;

print "the directory of my script is: " . $FindBin::Bin . "\n";
print "the base name of my script is: " . $FindBin::Script . "\n";
print "the canonical location of my script is: " . File::Spec->catfile($FindBin::Bin, $FindBin::Script) . "\n";

Внутренне, вы можете получить часть этой информации, посмотрев $0 (имя скрипта, которое вызывается в командной строке), и __FILE__, который является именем исполняемого в данный момент файла. (См. perldoc perlvar .)

Чтобы извлечь имя файла исполняемого в данный момент модуля , начните с изучения __PACKAGE__, выполните магию подстановки, а затем найдите имя файла в %INC:

(my $filename = __PACKAGE__ ) =~ s#::#/#g;
$filename .= '.pm';
my $abs_filename = $INC{$filename};

Я делаю это в одной из моих библиотек инициализации, чтобы найти скрипт конфигурации в пути относительно текущего модуля (у меня установлено несколько веток кода, расположенных рядом, каждая со слегка отличающимися конфигами):

# use the location of the current module as a guide for where to find configs
(my $filename = __PACKAGE__ ) =~ s#::#/#g;
$filename .= '.pm';

(my $path = $INC{$filename}) =~ s#/\Q$filename\E$##g; # strip / and filename
my $abs_config_file = File::Spec->catfile($path, $config_file);
MyApp->initialize($abs_config_file);
1 голос
/ 08 марта 2010

Это фрагмент, который я обычно использую для получения пути к исполняемому коду.

use Cwd qw/abs_path/;
my ($real_path) = abs_path($0) =~ m/(.*)myscript.pl/i;

Это помещает фактический путь к каталогу в $ real_path. Я обычно также выполняю chdir $real_path после этого, чтобы убедиться, что мой код действительно работает из каталога, которым он должен быть (обычно, когда я пишу службу Windows, используя Win32 :: Daemon).

Подпрограмма abs_path, которую я экспортировал, дает путь к любому файлу (имя / дескриптор), который вы предоставляете в качестве аргумента. В этом случае я указал $0, которое является именем выполняемого сценария Perl.

Я бы порекомендовал проверить Cwd на Cpan для более подробных указаний.

1 голос
/ 08 марта 2010

Любые библиотеки, включенные через use или require, создают запись в специальном хеше %INC. (См. perlvar ).

Например:

use strict;
use warnings;

use Data::Dumper;

print Dumper \%INC;

Это выдаст результат, подобный следующему:

$VAR1 = {
      'warnings/register.pm' => '/usr/lib/perl5/5.8.8/warnings/register.pm',
      'bytes.pm' => '/usr/lib/perl5/5.8.8/bytes.pm',
      'XSLoader.pm' => '/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/XSLoader.pm',
      'Carp.pm' => '/usr/lib/perl5/5.8.8/Carp.pm',
      'Exporter.pm' => '/usr/lib/perl5/5.8.8/Exporter.pm',
      'strict.pm' => '/usr/lib/perl5/5.8.8/strict.pm',
      'warnings.pm' => '/usr/lib/perl5/5.8.8/warnings.pm',
      'overload.pm' => '/usr/lib/perl5/5.8.8/overload.pm',
      'Data/Dumper.pm' => '/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/Data/Dumper.pm'
    };

Кроме того, есть универсальная __FILE__ константа, которая будет возвращать текущее имя файла. (См. Также __PACKAGE__).

0 голосов
/ 20 июня 2014

Самый простой способ:

print $ENV{'PWD'};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...