Подтвердить что ты не робот

Как мой 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 делает этот вопрос абсолютно излишним.
4b9b3361

Ответ 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.