108

Aside from trying

perldoc <module name>

individually for any CPAN module that takes my fancy or going through the file system and looking at the directories, I have no idea what modules we have installed.

What's the easiest way to just get a big list of every CPAN module installed? From the command line or otherwise.

toolic
  • 57,801
  • 17
  • 75
  • 117
David McLaughlin
  • 5,108
  • 4
  • 34
  • 35

27 Answers27

73

This is answered in the Perl FAQ, the answer which can be quickly found with perldoc -q installed. In short, it comes down to using ExtUtils::Installed or using File::Find, variants of both of which have been covered previously in this thread.

You can also find the FAQ entry "How do I find which modules are installed on my system?" in perlfaq3. You can see a list of all FAQ answers by looking in perlfaq

brian d foy
  • 129,424
  • 31
  • 207
  • 592
pjf
  • 5,993
  • 25
  • 42
  • 41
    This gives so much more than the OP requested that it is virtually useless. – Justin Mar 07 '14 at 20:32
  • 2
    cpan -l is doing a recursive search of whatever directory I run it from. Is there any way to pass the `ExtUtils::Installed` constructor's `skip_cwd` option from that command line? – Mark Reed Oct 20 '14 at 15:10
  • 11
    The FAQ says to use `cpan -l` but that doesn't work on RHEL6, and `/usr/bin/cpan -l` throws the error `Unknown option: l`. – Stefan Lasiewski Mar 14 '16 at 19:24
  • 1
    $ perldoc perllocal | grep Module $ perldoc perllocal | grep -E 'VERSION|Module' – caot Jun 22 '17 at 21:13
  • use perldoc -t perllocal to get plain text output, otherwise grep may not work due to embedded ctrl characters – user333869 Nov 27 '17 at 07:32
  • @caot `perldoc perllocal | grep -E 'VERSION|Module > perlmods.txt` - nice way of filtering the long readout, so I piped into a file – Dave Everitt Jul 14 '20 at 18:50
42
perldoc perllocal

Edit: There's a (little) more info about it in the CPAN FAQ

Dan
  • 61,568
  • 9
  • 61
  • 78
37

perldoc -q installed

claims that cpan -l will do the trick, however it's not working for me. The other option:

cpan -a

does spit out a nice list of installed packages and has the nice side effect of writing them to a file.

Paul Rubel
  • 26,632
  • 7
  • 60
  • 80
29
$ for M in `perldoc -t perllocal|grep Module |sed -e 's/^.*" //'`; do V=`perldoc -t perllocal|awk "/$M/{y=1;next}y" |grep VERSION |head -n 1`; printf "%30s %s\n" "$M" "$V"; done |sort
              Class::Inspector     *   "VERSION: 1.28"
                    Crypt::CBC     *   "VERSION: 2.33"
               Crypt::Rijndael     *   "VERSION: 1.11"
                    Data::Dump     *   "VERSION: 1.22"
                   DBD::Oracle     *   "VERSION: 1.68"
                           DBI     *   "VERSION: 1.630"
                   Digest::SHA     *   "VERSION: 5.92"
           ExtUtils::MakeMaker     *   "VERSION: 6.84"
                       install     *   "VERSION: 6.84"
               IO::SessionData     *   "VERSION: 1.03"
               IO::Socket::SSL     *   "VERSION: 2.016"
                          JSON     *   "VERSION: 2.90"
                  MIME::Base64     *   "VERSION: 3.14"
                  MIME::Base64     *   "VERSION: 3.14"
                   Mozilla::CA     *   "VERSION: 20141217"
                   Net::SSLeay     *   "VERSION: 1.68"
                        parent     *   "VERSION: 0.228"
                  REST::Client     *   "VERSION: 271"
                    SOAP::Lite     *   "VERSION: 1.08"
                  Task::Weaken     *   "VERSION: 1.04"
                 Term::ReadKey     *   "VERSION: 2.31"
                Test::Manifest     *   "VERSION: 1.23"
                  Test::Simple     *   "VERSION: 1.001002"
                  Text::CSV_XS     *   "VERSION: 1.16"
                     Try::Tiny     *   "VERSION: 0.22"
                   XML::LibXML     *   "VERSION: 2.0108"
         XML::NamespaceSupport     *   "VERSION: 1.11"
                XML::SAX::Base     *   "VERSION: 1.08"
Dan
  • 291
  • 3
  • 4
24

It's worth noting that perldoc perllocal will only report on modules installed via CPAN. If someone installs modules manually, it won't find them. Also, if you have multiple people installing modules and the perllocal.pod is under source control, people might resolve conflicts incorrectly and corrupt the list (this has happened here at work, for example).

Regrettably, the solution appears to be walking through @INC with File::Find or something similar. However, that doesn't just find the modules, it also finds related modules in a distribution. For example, it would report TAP::Harness and TAP::Parser in addition to the actual distribution name of Test::Harness (assuming you have version 3 or above). You could potentially match them up with distribution names and discard those names which don't match, but then you might be discarding locally built and installed modules.

I believe brian d foy's backpan indexing work is supposed to have code to hand it at .pm file and it will attempt to infer the distribution, but even this fails at times because what's in a package is not necessarily installed (see Devel::Cover::Inc for an example).

Ovid
  • 11,580
  • 9
  • 46
  • 76
  • 1
    I don't think I need to pull out the BackPAN catalog guns for that one. Something like I do with Test::Prereq to collapse it by what distro it finds in 02packages might be enough. That is a little tricker than just listing the module files though, and the catalog isn't close to handling that yet. – brian d foy Sep 22 '08 at 20:27
  • 2
    From a rudimentary test (doing a "make -n install" in some dirs I have laying around), the "make install" step of any MakeMaker-based module will update perllocal. It's not specific to installing via CPAN directly. – rjray Sep 22 '08 at 23:12
  • 1
    I think Dist::Surveyor is still the best tool for answering the question "what *distributions* are installed in that library?". See [this presentation](http://www.slideshare.net/Tim.Bunce/perl-distsurveyor-2011) for more details. There's an easy-to-use fatpacked version in the [git repo](https://github.com/timbunce/Dist-Surveyor/network). – Tim Bunce Sep 11 '13 at 17:12
20

You can try ExtUtils-Installed, but that only looks in .packlists, so it may miss modules that people moved things into @INC by hand.

I wrote App-Module-Lister for a friend who wanted to do this as a CGI script on a non-shell web hosting account. You simple take the module file and upload it as a filename that your server will treat as a CGI script. It has no dependencies outside of the Standard Library. Use it as is or steal the code.

It outputs a list of the modules and their versions:

Tie::Cycle      1.15
Tie::IxHash     1.21
Tie::Toggle     1.07
Tie::ToObject   0.03
Time::CTime     99.062201
Time::DaysInMonth       99.1117
Time::Epoch     0.02
Time::Fuzzy     0.34
Time::JulianDay 2003.1125
Time::ParseDate 2006.0814
Time::Timezone  2006.0814

I've been meaning to add this as a feature to the cpan tool, so I'll do that too. [Time passes] And, now I have a -l switch in cpan. I have a few other things to do with it before I make a release, but it's in github. If you don't want to wait for that, you could just try the -a switch to create an autobundle, although that puts some Pod around the list.

Good luck;

brian d foy
  • 129,424
  • 31
  • 207
  • 592
14

Here a script which would do the trick:

use ExtUtils::Installed;

my $inst = ExtUtils::Installed->new();
my @modules = $inst->modules();
foreach $module (@modules){
       print $module ." - ". $inst->version($module). "\n";
}

=head1 ABOUT

This scripts lists installed cpan modules using the ExtUtils modules

=head1 FORMAT

Prints each module in the following format
<name> - <version>

=cut
JamesThomasMoon
  • 6,169
  • 7
  • 37
  • 63
Joakim
  • 510
  • 4
  • 10
10

Try the following command

instmodsh

With l you will List all installed modules.

From man page:

A shell to examine installed modules.
A little interface to ExtUtils::Installed to examine installed modules, validate your packlists and even create a tarball from an installed module.

Pablo Bianchi
  • 1,824
  • 1
  • 26
  • 30
user2024286
  • 119
  • 1
  • 2
9

I like to use the CPAN 'r' command for this. You can get into the CPAN shell with the old style:

sudo perl -MCPAN -e shell

or, on most newer systems, there is a 'cpan' command, so this command will get you to the shell:

sudo cpan

(You typically have to use 'sudo' to run it as root, or use 'su -' to become root before you run it, unless you have cpan set up to let you run it as a normal user, but install as root. If you don't have root on this machine, you can still use the CPAN shell to find out this information, but you won't be able to install modules, and you may have to go through a bit of setup the first time you run it.)

Then, once you're in the cpan shell, you can use the 'r' command to report all installed modules and their versions. So, at the "cpan>" prompt, type 'r'. This will list all installed modules and their versions. Use '?' to get some more help.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
amoore
  • 445
  • 2
  • 4
  • 1
    actually 'r' gives you the reinstall recommendations - ie all the modules on your install that have a newer version of CPAN. Unless your install is very out of date this will not be a complete list. – EvdB Sep 22 '08 at 15:56
  • My 'r' always reports next to nothing because I upgrade compulsively. Which reminds me ... I haven't upgraded today, yet. – skiphoppy Sep 22 '08 at 16:19
  • 3
    The -r recompiles stuff. To get a list, try -a or download the latest sources and play with the new -l switch, added for just this answer. :) – brian d foy Sep 22 '08 at 20:28
  • 1
    Why the `sudo` here? It’s completely unnecessary. – Aristotle Pagaltzis Sep 23 '08 at 07:45
  • 2
    note the difference between the '-r' commandline argument to 'cpan', and the 'r' command in the cpan shell :) – EvdB Sep 23 '08 at 09:48
  • Use of `sudo` is not recommended, as it affects the system packages and modules. AFAIK, at least in recent versions, `cpan` performs the setup automatically that creates a local installation for the regular user in the `$HOME` directory. – ILMostro_7 Jan 01 '19 at 17:48
8
perl -MFile::Find=find -MFile::Spec::Functions -Tlwe 'find { wanted => sub { print canonpath $_ if /\.pm\z/ }, no_chdir => 1 }, @INC'
slayedbylucifer
  • 22,878
  • 16
  • 94
  • 123
  • This is very good as it clearly show the full path to each `*.pm` module. You may see many duplicates... – not2qubit Jan 31 '19 at 23:27
8

You can get list of perl modules installed in you system by using instmodsh command in your terminal.It will ask you three option in order to enhance the output they are:

   l            - List all installed modules
   m <module>   - Select a module
   q            - Quit the program
Thiyagu ATR
  • 2,224
  • 7
  • 30
  • 44
8

On Linux/Unix I use this simple command:

perl -e 'print qx/find $_ -name "*.pm"/ foreach ( @INC );' 

It scans all folder in @INC and looks for any *.pm file.

Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110
7

Here's a really hacky way to do it in *nix, you'll get some stuff you don't really care about (ie: warnings::register etc), but it should give you a list of every .pm file that's accessible via perl.


for my $path (@INC) {
    my @list = `ls -R $path/**/*.pm`;
    for (@list) {
        s/$path\///g;
        s/\//::/g;
        s/\.pm$//g;
        print;
    }
}

shelfoo
  • 1,569
  • 13
  • 15
  • 2
    This will not give him what he wants. It won't group related files by the distribution they are part of, and it will list all the core *.pm files from Perl itself. – rjray Sep 22 '08 at 23:14
4

All those who can't install perldoc, or other modules, and want to know what modules are available (CPAN or otherwise), the following works for linux and Mingw32/64:

grep -RhIP '^package [A-Z][\w:]+;' `perl -e 'print join " ",@INC'` | sed 's/package //' | sort | uniq

Yes, it's messy. Yes, it probably reports more than you want. But if you pipe it into a file, you can easily check for, say, which dbm interfaces are present:

 grep -RhIP '^package [A-Z][\w:]+;' `perl -e 'print join " ",@INC'` | sed 's/package //' | sort | uniq > modules-installed
 cat modules-installed | grep -i dbm 

AnyDBM_File;
Memoize::AnyDBM_File;
Memoize::NDBM_File;
Memoize::SDBM_File;
WWW::RobotRules::AnyDBM_File;

Which is why I ended up on this page (disappointed)

(I realise this doesn't answer the OP's question exactly, but I'm posting it for anybody who ended up here for the same reason I did. That's the problem with stack*** it's almost imposisble to find the question you're asking, even when it exists, yet stack*** is nearly always google's top hit!)

4

Here's a script by @JamesThomasMoon1979 rewritten as a one-liner

perl -MExtUtils::Installed -e '$i=ExtUtils::Installed->new(); 
      print "$_ ".$i->version($_)."\n" for $i->modules();'
Nicholas Sushkin
  • 13,050
  • 3
  • 30
  • 20
2

The answer can be found in the Perl FAQ list.

You should skim the excellent documentation that comes with Perl

perldoc perltoc
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
2

Try man perllocal or perldoc perllocal.

Walter H
  • 151
  • 7
1

To walk through the @INC directory trees without using an external program like ls(1), one could use the File::Find::Rule module, which has a nice declarative interface.

Also, you want to filter out duplicates in case previous Perl versions contain the same modules. The code to do this looks like:

#! /usr/bin/perl -l

use strict;
use warnings;
use File::Find::Rule;

my %seen;
for my $path (@INC) {
    for my $file (File::Find::Rule->name('*.pm')->in($path)) {
        my $module = substr($file, length($path)+1);
        $module =~ s/.pm$//;
        $module =~ s{[\\/]}{::}g;
        print $module unless $seen{$module}++;
    }
}

At the end of the run, you also have all your module names as keys in the %seen hash. The code could be adapted to save the canonical filename (given in $file) as the value of the key instead of a count of times seen.

Randall
  • 2,859
  • 1
  • 21
  • 24
dland
  • 4,319
  • 6
  • 36
  • 60
1

Here is yet another command-line tool to list all installed .pm files:

Find installed Perl modules matching a regular expression

  • Portable (only uses core modules)
  • Cache option for faster look-up's
  • Configurable display options
toolic
  • 57,801
  • 17
  • 75
  • 117
1

The following worked for me.

$ perldoc perllocal | grep Module
$ perldoc perllocal | grep -E 'VERSION|Module'
caot
  • 3,066
  • 35
  • 37
  • `perldoc perllocal | grep "::" | cut -d" " -f9 | sort`. I wonder why is not the same output as with `instmodsh`. – Pablo Bianchi Jul 08 '22 at 22:15
  • @PabloBianchi referring to Dan's answer behind, The entries of DBI, JSON, ... do not have any "::". It's my guess. It's easy for you to understand the difference in you system. – caot Jul 09 '22 at 15:25
1

I wrote a perl script just yesterday to do exactly this. The script returns the list of perl modules installed in @INC using the '::' as the separator. Call the script using -

perl perlmod.pl

OR

perl perlmod.pl <module name> #Case-insensitive(eg. perl perlmod.pl ftp)

As of now the script skips the current directory('.') since I was having problems with recursing soft-links but you can include it by changing the grep function in line 17 from

  grep { $_ !~ '^\.$' } @INC

to just,

@INC

The script can be found here.

aks
  • 24,359
  • 3
  • 32
  • 35
0
cd /the/lib/dir/of/your/perl/installation
perldoc $(find . -name perllocal.pod)

Windows users just do a Windows Explorer search to find it.

рüффп
  • 5,172
  • 34
  • 67
  • 113
mpersico
  • 766
  • 7
  • 19
0

Try "perldoc -l":

$ perldoc -l Log::Dispatch /usr/local/share/perl/5.26.1/Log/Dispatch.pm

Haili Sun
  • 621
  • 8
  • 13
0

the Perl cookbook contains several iterations of a script "pmdesc" that does what you want. Google-search for "Perl Cookbook pmdesc" and you'll find articles on other Q&A Sites, several code listings on the net, a discussion of the solution, and even some refinements.

knb
  • 9,138
  • 4
  • 58
  • 85
0

Here's a Perl one-liner that will print out a list of installed modules:

perl -MExtUtils::Installed -MData::Dumper -e  'my ($inst) = ExtUtils::Installed->new(); print Dumper($inst->modules());'

Just make sure you have Data::Dumper installed.

thealexbaron
  • 1,558
  • 1
  • 11
  • 25
-1

As you enter your Perl script you have all the installed modules as .pm files below the folders in @INC so a small bash script will do the job for you:

#!/bin/bash

echo -e -n "Content-type: text/plain\n\n"

inc=`perl -e '$, = "\n"; print @INC;'`

for d in $inc
do
   find $d -name '*.pm'
done
Henrik
  • 332
  • 3
  • 12
-1

For Linux the easiest way to get is,

dpkg -l | grep "perl"
Yasiru G
  • 6,886
  • 6
  • 23
  • 43
  • 1
    the OP asked for a list of CPAN (perl) modules installed in the system, not if perl is installed in the system (neither the OP told us if apt is available) – ROLO Mar 12 '18 at 12:03
  • I'm not a perl expert but I have seen installed perl modules from above command. May be not the perfect answer here. – Yasiru G Mar 13 '18 at 05:45
  • @YasiruG it only lists those that have been installed via packages; that's a minority in any installation. Most of them are installed via CPAN. – jjmerelo Dec 28 '20 at 09:03