Если я в каком-то библиотечном коде, как определить путь к файлу кода, который в настоящее время выполняется? Я знаю, как получить путь к верхнему файлу perl, посмотрев на ARGV
, но если я загружу библиотеку, как эта библиотека может узнать, к какому пути она находится?
В Perl, как мне получить каталог или путь для текущего исполняемого кода?
Ответ 1
Ток __FILE__
предоставит вам полный путь, включая имя файла. Вы можете использовать File:: Spec, чтобы разбить его на компоненты:
my ($volume, $directory, $file) = File::Spec->splitpath(__FILE__);
Ответ 2
Самый простой способ найти имя файла текущего исполняемого файла: 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
(имя script как вызывается в командной строке) и __FILE__
, который является именем исполняемого файла, (См. perldoc perlvar.)
Чтобы извлечь имя файла текущего исполняемого модуля, начните с изучения __PACKAGE__
, выполните некоторую магию замещения, а затем найдите имя файла в %INC
:
(my $filename = __PACKAGE__ ) =~ s#::#/#g;
$filename .= '.pm';
my $abs_filename = $INC{$filename};
Я делаю это в одной из моих инициализационных библиотек, чтобы найти конфигурацию script в пути относительно текущего модуля (у меня есть несколько ветвей кода, установленных бок о бок, каждый со слегка разными конфигурациями):
# 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);
Ответ 3
Любые библиотеки, включенные через 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__
).
Ответ 4
Это фрагмент, который я обычно использую, чтобы получить путь для исполняемого кода.
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 script.
Я бы рекомендовал проверить Cwd на Cpan для получения более подробной информации.
Ответ 5
Самый простой способ:
print $ENV{'PWD'};