Как я могу проверить, установлен ли модуль Perl в моей системе из командной строки? - PullRequest
54 голосов
/ 24 июня 2009

Я пытался проверить, установлен ли в моей системе XML :: Simple.

perl -e 'while (<@INC>) { while (<$_/*.pm>) { print "$_\n"; } }'

Вышеупомянутый однострочный использовался для перечисления всех модулей, установленных в моей системе Тем не менее, он не перечисляет модули XML.

Тем не менее, следующее выполняется нормально.

perl -e "use XML::Simple "

В чем может быть проблема?

Ответы [ 10 ]

90 голосов
/ 24 июня 2009

Вы можете проверить путь установки модуля:

perldoc -l XML::Simple

Проблема вашего однострочного заключается в том, что он не рекурсивно пересекает каталоги / подкаталоги. Следовательно, вы получаете только прагматичные имена модулей в качестве вывода.

37 голосов
/ 24 июня 2009

Быстро и грязно:

$ perl -MXML::Simple -e 1
17 голосов
/ 24 июня 2009
$ perl -MXML::Simple -le 'print $INC{"XML/Simple.pm"}'

Начиная с записи perlvar на %INC:

  • % INC

Хэш %INC содержит записи для каждого имени файла, включенные с помощью операторов do, require или use. Ключ - это имя файла, которое вы указали (с именами модулей, преобразованными в пути), а значение - это местоположение найденного файла. Оператор require использует этот хэш, чтобы определить, был ли конкретный файл уже включен.

Если файл был загружен через ловушку (например, ссылку на подпрограмму, см. требуют для описания этих ловушек), эта ловушка по умолчанию вставляется в %INC вместо имени файла. Однако обратите внимание, что ловушка, возможно, сама установила запись% INC, чтобы предоставить более конкретную информацию.

12 голосов
/ 01 марта 2013

Например, чтобы проверить, установлен модуль DBI или нет, используйте

perl -e 'use DBI;'

Вы увидите ошибку, если не установлена. (от http://www.linuxask.com)

9 голосов
/ 24 июня 2009

То, что вы там делаете, не повторяется в каталогах. Это только перечисление модулей в корневом каталоге каталога @INC.

Модуль XML::Simple будет жить по одному из путей @INC в XML/Simple.pm.

То, что он сказал выше, чтобы найти конкретные модули.

CPAN объясняет, как найти все модули здесь, см. Как найти установленные модули .

7 голосов
/ 24 июня 2009

Если вы хотите быстро проверить, установлен ли модуль (по крайней мере, в системах Unix с Bash в качестве оболочки), добавьте это в ваш файл .bashrc:

alias modver="perl -e\"eval qq{use \\\$ARGV[0];\\\\\\\$v=\\\\\\\$\\\${ARGV[0]}::VERSION;};\ print\\\$@?qq{No module found\\n}:\\\$v?qq{Version \\\$v\\n}:qq{Found.\\n};\"\$1"

Тогда вы можете:

=> modver XML::Simple
No module found

=> modver DBI
Version 1.607
3 голосов
/ 11 марта 2010

Если вы работаете ActivePerl под Windows:

  • C:\>ppm query * для получения списка всех установленных модулей

  • C:\>ppm query XML-Simple, чтобы проверить, установлен ли XML::Simple

3 голосов
/ 24 июня 2009

while (<@INC>)

Это объединяет пути в @INC в строку, разделенную пробелами, затем вызывает glob () для строки, которая затем перебирает компоненты, разделенные пробелами (если только нет метасимволов с глобальными файлами).

Это не очень хорошо работает, если в @INC есть пути, содержащие пробелы, \, [], {}, *,? Или ~, и, кажется, нет причин избегать безопасной альтернативы:

for (@INC)
0 голосов
/ 21 февраля 2015

Bravo для решения @ user80168 (я все еще считаю \!), Но чтобы избежать всего побега, связанного с псевдонимами и оболочками:

%~/ cat ~/bin/perlmod
perl -le'eval qq{require $ARGV[0]; } 
    ? print ( "Found $ARGV[0] Version: ", eval "$ARGV[0]->VERSION" ) 
    : print "Not installed" ' $1

работает достаточно хорошо.

Здесь может быть самый простой и самый «современный» подход, использующий Module::Runtime:

perl -MModule::Runtime=use_module -E '
     say "$ARGV[0] ", use_module($ARGV[0])->VERSION' DBI

Это даст полезную ошибку, если модуль не установлен.

Использование -MModule::Runtime требует его установки (это не основной модуль).

0 голосов
/ 16 августа 2014

Я считаю, что ваше решение будет искать только в корне каждого пути к каталогу, содержащегося в массиве @INC. Вам нужно что-то рекурсивное, например:

 perl -e 'foreach (@INC) {
    print `find $_ -type f -name "*.pm"`;
 }'
...