如何获得已安装的 CPAN 模块的列表?

除了努力

perldoc <module name>

对于任何我喜欢的 CPAN 模块,或者浏览文件系统和查看目录,我不知道我们已经安装了哪些模块。

要获得安装的每个 CPAN 模块的大列表,最简单的方法是什么?从命令行或以其他方式。

256749 次浏览
perldoc perllocal

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

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.

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;
}
}

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).

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;

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.

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

The answer can be found in the Perl FAQ list.

You should skim the excellent documentation that comes with Perl

perldoc perltoc

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.

Try man perllocal or perldoc perllocal.

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

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

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.

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.

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.

perl -MFile::Find=find -MFile::Spec::Functions -Tlwe 'find { wanted => sub { print canonpath $_ if /\.pm\z/ }, no_chdir => 1 }, @INC'

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.

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
cd /the/lib/dir/of/your/perl/installation
perldoc $(find . -name perllocal.pod)

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

$ 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"

The following worked for me.

$ perldoc perllocal | grep Module
$ perldoc perllocal | grep -E 'VERSION|Module'

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

For Linux the easiest way to get is,

dpkg -l | grep "perl"

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.

Try "perldoc -l":

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

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!)

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();'