How do I find all modules used in a Perl script and install them? - perl

I have been given a few Perl scripts to deploy.
What is the easiest way to find and install all modules used by these scripts?
EDIT:
From what I can find there are no conditional includes or includes in evals.

Does my Module::Extract::Use help? There's an extract_modules program in the examples directory:
$ examples/extract_modules -l some_program
File::Spec
File::Spec::Functions
strict
warning
You can pipe that list to cpan.
$ examples/extract_modules -l some_program | xargs cpan
Once you have that list, which is only the first level of dependencies, you can make a script distribution that allows people to use the normal CPAN toolchain to install everything.
If there's something that doesn't work for you, modify the program to handle that. If you think it would be useful to other people, send a pull request. :)

I was hoping Module::ScanDeps which provides the command line utility scandeps.pl would be useful here but, to my dismay, Module::ScanDeps is apparently not intended for this particular purpose as scandeps.pl either ignores missing modules or (with -c or -x) croaks when the script uses a module that is not installed.
Here is a quick'n'dirty Perl script that tries to execute the script using do until it succeeds:
#!/usr/bin/perl
use strict;
use warnings;
use Term::Prompt;
my ($script) = #ARGV;
die "Provide script file name on the command line\n"
unless defined $script;
until ( do $script ) {
my $ex = $#;
if ( my ($file) = $ex =~ /^Can't locate (.+?) in/ ) {
my $module = $file;
$module =~ s/\.(\w+)$//;
$module = join('::', split '/', $module);
print "Attempting to install '$module' via cpan\n";
system(cpan => $module);
last unless prompt(y => 'Try Again?', '', 'n');
}
else {
die $ex;
}
}
If you do not want the script to be run, you can run perl -c $script, capture stderr output of that and parse for missing module messages and call cpan for each such module found until perl -c $script outputs "Syntax OK". That gives you a cleaner loop too. I'll look at this later.
You might miss dependencies loaded at run time using this technique.

Well this is the very simplistic way I solved this.
In a bash shell:
cat *.pl | grep "^use " | tr ';' ' ' | while read a b c; do echo $b; done | sort -iu > modules.txt
This gave me a file with only the module names, one on each line.
I then used this
cat modules.txt | while read a; do cpan $a; done
to invoke cpan to each module name in the file. And then sat there answering yes to CPAN's questions to install dependencies as appropriate.
Not pretty but this time it got the job done.

Or let PAR's pp do the work for you in collecting together everything you need in a single executable.

Related

How can I inspect the code of a perl module installed?

If I know that a certain perl module is installed on a system, eg. MyCompany::Database::Utils, how can I inspect the perl code of this module?
Find the source code file with whatever means your OS provides.
If you're looking for a properly installed module, you can use perldoc -l to find the file or perldoc -m to print the file (thanks #ThisSuitIsBlackNot, #mob):
perldoc -l List::Util
perldoc -m List::Util
If your module is MyCompany::Database::Utils, you know it must be in a path MyCompany/Database/Utils.pm below one of the paths in #INC.
You can list the default #INC paths with
perl -MData::Dumper -e 'print Dumper(\#INC);'
If you are on a system with mlocate (such as most Linux/BSD distros), you can also find the file with
locate MyCompany/Database/Utils.pm
If you want to look into a distribution to see the full source (e.g. to find XS code, README, unit tests etc.), you can use cpanminus' --look flag:
cpanm --look DateTime
Perl can find the module, so let Perl tell you where it found it!
perl -e'
my $p = $ARGV[0];
$p =~ s{::}{/}g;
$p .= ".pm";
require $p;
print "$INC{$p}\n";
' MyCompany::Database::Utils
If the module contains POD, you can use the following shortcut:
perldoc -l MyCompany::Database::Utils
If that doesn't find the module, it could be that the script that uses MyCompany::Database::Utils manipulates #INC to allow it to find the module. If so, add the following to your script:
END {
my $p = "MyCompany::Database::Utils";
$p =~ s{::}{/}g;
$p .= ".pm";
print "$INC{$p}\n";
}
The built-in hash %INC documented in perldoc perlvar relates each module's .pm source file to its file system location
If you have
use MyCompany::Database::Utils;
then perl will search for a file like MyCompany/Database/Utils.pm relative to any of the directories listed in array #INC and, if it is found, will put its absolute location into the %INC hash
To find where each module has been located, you can simply dump the entire hash using Data::Dump or Data::Dumper. But if you're really only interested in one module then you can examine the relevant hash element. A statement like this
print "$INC{'MyCompany/Database/Utils.pm'}\n";
will show the absolute path where that .pm file was found and loaded

How to see if a plugin is already installed with Perl

I have a Perl script that requires a couple of plugins, for istance nmap. How can I see if the plugins are already installed and, in case they are not, install them? I tryed with the following code but it doesn't work very well, what I am trying to do is capture the "bash: nmap: command not found" output. I tryed with both stdout and stderr.
print "Checking nmap...\n";
my ($stdout, $stderr) = capture {
system("nmap");
};
if ($stdout=~m/command not found/) {
print "nmap not found, installing...\n";
system("rpm -i nmap-4.75-1.26.x86_64.rpm");
}
else {
print "nmap is already installed.\n";
}
How can I see if the plugins are already installed and, in case they are not, install them?
This is not a good idea, do not check for dependencies at run time. Instead you declare the dependencies in your distro meta file and check for them at build time and perhaps abort the build. The easiest way to do so is with requires_external_bin from Module::Install. This integrates nicely into the existing RPM infrastructure. - In other words, learn the basics of packaging and which problems this solves.
If you cannot rely on the user having permission to install it system-wide, create an Alien distro that downloads the source and installs it into the share tree. But once you go down that rabbit hole, be aware that it's deep - you would also need to take care of the deps of nmap itself somehow.
What about this?
my $cmd='which nmap';
my $output = `$cmd 2>&1`;
my $exit_value=$? >> 8;
if ($exit_value){
print "not found $cmd, error: $output\n";
}else{
print "Found $cmd at $output\n";
}
Like daxim pointed out requires_external_bin from Module::Install::External is a good way to ensure that your binary is installed.
If you can't use Module::Install in your application you might try searching the PATH environment variable like this:
use File::Spec;
$\="\n";
print installed($_) ? "$_ installed" : "$_ not installed" for qw/nmap ls cat nosuchfile less/;
sub installed {
my $name = shift;
foreach my $path (File::Spec->path()) {
my $bin = File::Spec->catfile($path, $name);
return $bin if -e -f -x $bin;
}
}
This should output something like this:
$ perl test.pl
nmap installed
ls installed
cat installed
nosuchfile not installed
less installed
The downside of this is of course, that the binary you are looking for has to reside in $PATH.

How can I get the version and location of an installed Perl module?

Is there a smart way to detect whether a certain Perl module has been installed in your system?
My old sutpid way is to write a Perl script in which the only thing I do is just to use the module. If nothing croaks when I run the detect script, then I know the module has been installed, although I still don't know which version and where the module has been installed .
thanks in advance.
Something like:
perl -MModule -e 'print "$Module::VERSION\n"' 2>/dev/null || echo "Not installed"
would give you the version of a given module, or tell you it isn't installed. Usage would look like:
perl -MXML::Parser -e 'print "$XML::Parser::VERSION\n"' 2>/dev/null || echo "Not installed"
To find the module path, you could examine #INC to find possible locations, or you could perhaps look into perlwhich. There is also pmpath from pmtools.
The shortest thing I know of that doesn't involve a script or shell alias:
$ perl -MFoo::Bar\ 99
Foo::Bar version 99 required--this is only version 1.234.
(or the usual message about not being in #INC if it's not installed)
For the curious, this is the same as perl -e 'use Foo::Bar 99'.
instmodsh
NAME
instmodsh - A shell to examine installed modules
SYNOPSIS
instmodsh
DESCRIPTION
A little interface to ExtUtils::Installed to examine installed modules, validate your packlists and even create a tarball from an installed module.
SEE ALSO
ExtUtils::Installed
Here's a program which does that:
#!/usr/bin/perl
# testmod - test to see if a module is available
use strict;
use warnings;
my $mod = (shift #ARGV) || die "usage: $0 module\n";
# convert module-name to path
my $file = $mod;
$file =~ s{::}{/}gsmx;
$file .= '.pm';
# Pull in the module, if it exists
eval { require $file }
or die "can't find module $mod\n";
# Get the version from the module, if defined
my $ver;
{ no strict 'refs';
$ver = ${$mod . "::VERSION"} || 'UNKNOWN';
}
# And its location
my $from = $INC{$file};
print "module $mod is version $ver loaded from $from\n";
Use pmvers. Like the name suggests, it shows the version of an installed module. If a module is not installed, it fails with the familiar error message: Can't locate … in #INC (#INC contains: …)
Use pmpath from the same distribution to find a module's installation path.
I use these bash function/Perl oneliners to find the version number and location of Perl modules:
# equivalent to perldoc -l <module>
perlwhere() {
perl -wle'eval "require $ARGV[0]" or die; ($mod = $ARGV[0]) =~ s|::|/|g; print $INC{"${mod}.pm"}' $1
}
perlversion() {
perl -M$1 -wle'print $ARGV[0]->VERSION' $1
}
: [ether ~].2$; perlwhere Test::More
/usr/lib/perl5/5.8.8/Test/More.pm
: [ether ~].2$; perlversion Test::More
0.94
I don't know if there is any smart way for this. But what I usually
do is to make use of '-l' or '-m' option of perldoc. For example :
%perldoc -l XML::Simple
and the output is something like below,which is the full path of module file
.../lib/XML/Simple.pm
The advantage with this approach compared to yours is that, if the module is installed
the output contains the path for module location. However when the module is not
installed
or if it doesn't has a perldoc the error message shown is "No documentation found for ...",
making it impossible to distinguish if the error is due to missing module or missing
documentation. In such scenario the -m option becomes handy since it prints entire
contents of the file along with the path.
The pmvers utility and the other pmtools will do what you need. Otherwise here is a one-liner to find a module version:
perl -le 'eval "require $ARGV[0]" and print $ARGV[0]->VERSION' Some::Module
If you're looking for a cross-platform CLI (Linux, OSX, Windows), consider my whichpm utility; e.g.:
# Locate the Data::Dumper module, and also print
# version information and core-module status.
$ whichpm -v Data::Dumper
Data::Dumper 2.145 core>=5.005 /usr/lib/perl/5.18/Data/Dumper.pm
It can also find accidental duplicates and list all installed modules.
If you happen to have Node.js / io.js installed, you can install it from the npm registry:
[sudo] npm install whichpm -g
For manual installation instructions and more, see the repo; here's a direct download link to the latest version (will stay current).

How do you list all locally installed CPAN modules? [duplicate]

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.
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
perldoc perllocal
Edit: There's a (little) more info about it in the CPAN FAQ
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.
$ 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"
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;
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
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.
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'
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
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.
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;
}
}
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();'
The answer can be found in the Perl FAQ list.
You should skim the excellent documentation that comes with Perl
perldoc perltoc
Try man perllocal or perldoc perllocal.
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.
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
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.
The following worked for me.
$ perldoc perllocal | grep Module
$ perldoc perllocal | grep -E 'VERSION|Module'
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.
cd /the/lib/dir/of/your/perl/installation
perldoc $(find . -name perllocal.pod)
Windows users just do a Windows Explorer search to find it.
Try "perldoc -l":
$ perldoc -l Log::Dispatch
/usr/local/share/perl/5.26.1/Log/Dispatch.pm
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"

How do I get a list of installed CPAN modules?

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.
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
perldoc perllocal
Edit: There's a (little) more info about it in the CPAN FAQ
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.
$ 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"
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;
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
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.
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'
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
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.
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;
}
}
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();'
The answer can be found in the Perl FAQ list.
You should skim the excellent documentation that comes with Perl
perldoc perltoc
Try man perllocal or perldoc perllocal.
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.
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
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.
The following worked for me.
$ perldoc perllocal | grep Module
$ perldoc perllocal | grep -E 'VERSION|Module'
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.
cd /the/lib/dir/of/your/perl/installation
perldoc $(find . -name perllocal.pod)
Windows users just do a Windows Explorer search to find it.
Try "perldoc -l":
$ perldoc -l Log::Dispatch
/usr/local/share/perl/5.26.1/Log/Dispatch.pm
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"