76

I tried to check if XML::Simple is installed in my system or not.

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

The above one-liner was used for listing all modules installed in my system. However, it is not listing XML modules.

However, the following executes fine.

perl -e "use XML::Simple "

What might be the issue?

joe
  • 34,529
  • 29
  • 100
  • 137
  • @Sinan: you changed the question a bit too much. I think the original question was how to find out where a module is installed. Now it's whether a module is installed. – innaM Jun 24 '09 at 16:36
  • I really have no idea. But considering the current question, your answer is pretty much the best so far. Maybe Chells can enlighten us. – innaM Jun 24 '09 at 16:43
  • 1
    @Sinan: why'd you retag from perl-module to perl-modules when the latter is barely used? – Greg Bacon Jun 24 '09 at 17:26
  • http://theunixshell.blogspot.in/2012/12/check-for-installed-modules-in-perl.html – Vijay Apr 17 '14 at 19:18

11 Answers11

111

You can check for a module's installation path by:

perldoc -l XML::Simple

The problem with your one-liner is that, it is not recursively traversing directories/sub-directories. Hence, you get only pragmatic module names as output.

Alan Haggai Alavi
  • 72,802
  • 19
  • 102
  • 127
  • 1
    Of course, this will only work if the module you are looking for contains POD. – innaM Jun 24 '09 at 15:51
  • 1
    @Manni: Should work with most modules (from CPAN) as all of them are documented. – Alan Haggai Alavi Jun 24 '09 at 16:09
  • 1
    Some of them are so well documented that they have their docs in their own .pod files. It's a nice trick that works most of the time with that one little gotcha. – innaM Jun 24 '09 at 16:13
  • 3
    This only works if the module contains Pod. Strange but true. – brian d foy Jun 24 '09 at 18:22
  • 2
    You should use `-lm` instead of `-l`. It the's same, except that it also works if the module has no POD. – ikegami Aug 04 '17 at 18:39
  • @briandfoy I think -l -m makes that work (and also gives the module path if they have a separate .pod file) – ysth Aug 04 '17 at 21:01
  • 2
    Unfortunately, on my server perldoc is not installed: "You need to install the perl-doc package to use this program." – user4035 Aug 26 '20 at 07:06
54

Quick and dirty:

$ perl -MXML::Simple -e 1
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
22
$ perl -MXML::Simple -le 'print $INC{"XML/Simple.pm"}'

From the perlvar entry on %INC:

  • %INC

The hash %INC contains entries for each filename included via the do, require, or use operators. The key is the filename you specified (with module names converted to pathnames), and the value is the location of the file found. The require operator uses this hash to determine whether a particular file has already been included.

If the file was loaded via a hook (e.g. a subroutine reference, see require for a description of these hooks), this hook is by default inserted into %INC in place of a filename. Note, however, that the hook may have set the %INC entry by itself to provide some more specific info.

Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
19

For example, to check if the DBI module is installed or not, use

perl -e 'use DBI;'

You will see error if not installed. (from http://www.linuxask.com)

demongolem
  • 9,474
  • 36
  • 90
  • 105
Hamidjon
  • 191
  • 1
  • 2
12

If you want to quickly check if a module is installed (at least on Unix systems, with Bash as shell), add this to your .bashrc file:

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"

Then you can:

=> modver XML::Simple
No module found

=> modver DBI
Version 1.607
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
9

What you're doing there is not recursing into directories. It is only listing the modules in the root directory of the @INC directory.

The module XML::Simple will live in one of the @INC paths under XML/Simple.pm.

What he said above to find specific modules.

CPAN explains how to find all modules here, see How to find installed modules.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Salgar
  • 7,687
  • 1
  • 25
  • 39
3

while (<@INC>)

This joins the paths in @INC together in a string, separated by spaces, then calls glob() on the string, which then iterates through the space-separated components (unless there are file-globbing meta-characters.)

This doesn't work so well if there are paths in @INC containing spaces, \, [], {}, *, ?, or ~, and there seems to be no reason to avoid the safe alternative:

for (@INC)
ysth
  • 96,171
  • 6
  • 121
  • 214
3

If you're running ActivePerl under Windows:

  • C:\>ppm query * to get a list of all installed modules

  • C:\>ppm query XML-Simple to check if XML::Simple is installed

Zaid
  • 36,680
  • 16
  • 86
  • 155
0

I believe your solution will only look in the root of each directory path contained in the @INC array. You need something recursive, like:

 perl -e 'foreach (@INC) {
    print `find $_ -type f -name "*.pm"`;
 }'
GL2014
  • 6,016
  • 4
  • 15
  • 22
  • This doesn't properly quote `$_`; if it contains spaces, it'll break at the words; if it contains `;` it'll break the command ([shell injection](https://en.wikipedia.org/wiki/Code_injection#Shell_injection)) - quote using either `String::ShellQuote` or the not-quite optimal solution of using the `quotemeta` built-in. – amphetamachine Apr 10 '23 at 19:09
0

Bravo for @user80168's solution (I'm still counting \'s !) but to avoid all the escaping involved with aliases and shells:

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

works reasonably well.

Here might be the simplest and most "modern" approach, using Module::Runtime:

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

This will give a useful error if the module is not installed.

Using -MModule::Runtime requires it to be installed (it is not a core module).

G. Cito
  • 6,210
  • 3
  • 29
  • 42
0

You can use cpan -D module. See here

In your case cpan -D XML::Simple.

It will tell you where the module is installed as well as if it is up-to-date.

AJ Dhaliwal
  • 661
  • 1
  • 8
  • 24