Как мой Perl script найдет свой модуль в том же каталоге?
Недавно я написал новый Perl script для уничтожения процессов на основе имени или имени процесса и расширения его с помощью классов, чтобы я мог повторно использовать код процесса в других программах. Мой текущий макет -
/home/mutew/src/prod/pskill <-- Perl script
/home/mutew/src/prod/Process.pm <-- Package to handle process descriptions
Я добавил ~/src/prod в свою переменную $PATH для доступа к script из любого места. При запуске script из любого каталога, кроме его резидентного каталога, появляется сообщение "Can not locate Process.pm in @INC" (что понятно, учитывая, что кроме общих каталогов в /usr, @INC включает только текущий directory - '.'). Одним из способов обхода, который я использовал, является директива use lib как таковая -
use lib '/home/mutew/src/prod';
но это серьезная проблема переносимости. Любые решения, которые также позволят мне экспортировать script в другие системы без изменений?
ИЗМЕНИТЬ
- Я выбрал ответ "depesz" как правильный из-за его простоты и использования основного модуля.
- brian d foy answer, хотя предлагает другие методы для достижения того же (TMTOWTDI), его вклад в perlfaq8 делает этот вопрос абсолютно излишним.
Ответы
Ответ 1
Самый простой подход я нашел, что он использует модуль FindBin. Вот так:
use FindBin;
use lib $FindBin::Bin;
Обычно я предпочитаю, чтобы мои сценарии были предоставлены таким образом, что программы находятся в любом /bin, а библиотеки находятся в любом /lib
В этих ситуациях я использую несколько более сложный подход:
use Cwd qw(abs_path);
use FindBin;
use lib abs_path("$FindBin::Bin/../lib");
Вызов abs_path заключается в том, чтобы @INC содержал все /lib, а не что-то/bin/../lib - это просто небольшое изменение, но облегчает чтение сообщений об ошибках.
Ответ 2
Мне любопытно, почему упрощенное решение
use File::Basename;
use lib dirname (__FILE__);
use SomeModuleLocatedInTheSameDirectoryAsThisPerlScriptOrModule;
не придумал. У модуля FindBin есть некоторые проблемы, если файл не является основным исполняемым perl script, а просто невыполнимым модулем Perl. По крайней мере, как я интерпретирую комментарий в документации. На самом деле это не проверял.
Чтобы иметь какой-либо другой путь относительно местоположения этого файла Perl, сделайте что-то вроде
use File::Basename;
use lib dirname (__FILE__) . "/MyModules";
Ответ 3
Из perlfaq8, который отвечает "Как добавить в мой путь включения (@INC) во время выполнения?" . Есть еще несколько ответов на вопросы по этому вопросу.
Как добавить каталог в мой путь 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
Посмотрите Par:: Packer, он создает исполняемый файл со всеми включенными зависимостями скриптов. Это облегчает распространение. Вы также можете предоставить своим пользователям версию своего модуля, которая может быть установлена в их системах. См. Module:: Starter для простого способа создания всех файлов, необходимых для создания стандартного дистрибутива стиля CPAN.
Ответ 5
Чтобы преобразовать относительные ссылки в абсолютный и добавить в @INC, я обычно использую ex:: lib. Конечно, это полезно, только если вы планируете сохранять относительные местоположения script и модуля одинаковыми на всех машинах, где вы планируете запустить script.
Ответ 6
Вы можете сделать perl look в любом каталоге, используя флаг -I
. Здесь -I
обозначает @INC
, который является массивом путей, в которых perl ищет модули. Использование -I
добавляет заданный путь к массиву @INC
для этого выполнения.
например:
perl -I lib bin/script.pl
где lib содержит модули, которые я хочу использовать.
Я знаю, что это работает для perl 5. Я не уверен в других версиях.
Ответ 7
FindBin:: libs найдет все ваши библиотеки, размещенные в разумных местах относительно пути, из которого выполняется ваш script.
Ответ 8
Просто сделай это простым. Нет необходимости импортировать библиотеки; просто найдите свой текущий рабочий каталог:
use lib "$ENV{PWD}/relativ_path_own_perllib";
Для подобных проблем вы можете прочитать переменную окружения, которая дает вашу информацию о том, где вы находитесь, домашний каталог, материал операционной системы и т.д., с одной строкой кода программирования в shell-терминале, например:
perl -e 'map { print; print " : ". $ENV{$_}." \n\r"; } sort keys %ENV '
Нет необходимости связывать некоторые библиотеки; просто используйте %ENV-Hash
.