I'm packaging clusterssh to openSUSE and need to change default shebang from #!/usr/bin/env perl to #!/usr/bin/perl. clusterssh uses Module::Build.
I'll probably use the patch (as Debian package do), but I wonder easy usage for fix_shebang_line(#files) in RPM packaging.
It's already called during the building process.
Basically, uninstalled scripts should use #!/usr/bin/perl or #!perl, and the installation process should rewrite that to the point to the perl used to run the installer. That way, a script installed by /usr/bin/perl will use /usr/bin/perl, and a script installed using /home/ikegami/usr/perlbrew/perls/5.26.2t/bin/perl will use /home/ikegami/usr/perlbrew/perls/5.26.2t/bin/perl.
(This applies to both the Module::Build installer and the ExtUtils::MakeMaker installer.)
Note that the documentation for fix_shebang_line says it doesn't touch a shebang line of #!/usr/bin/env perl (because it's not recognized as invocation of perl), so simply patching the scripts to use #!/usr/bin/perl instead of #!/usr/bin/env perl does the trick.
With that change, the install-ready staging directory (blib) produced by ./Build will contain the edited files.
$ perl -e'CORE::say $^X'
/home/ikegami/usr/perlbrew/perls/5.26.2t/bin/perl
$ for fn in ccon crsh csftp cssh ctel; do printf '%-6s ' "$fn:"; head -n 1 "bin_PL/$fn"; done
ccon: #!/usr/bin/perl
crsh: #!/usr/bin/perl
csftp: #!/usr/bin/perl
cssh: #!/usr/bin/perl
ctel: #!/usr/bin/perl
$ perl Build.PL
Could not get valid metadata. Error is: ERROR: Missing required field 'dist_abstract' for metafile
Could not create MYMETA files
Creating new 'Build' script for 'App-ClusterSSH' version 'v4.13.203'
$ ./Build
Building App-ClusterSSH
Using perl binary: /home/ikegami/usr/perlbrew/perls/5.26.2t/bin/perl
Using perl version v5.26.2
Generating: /home/ikegami/tmp/clusterssh/bin_PL/cssh
Generating: /home/ikegami/tmp/clusterssh/bin_PL/csftp
Generating: /home/ikegami/tmp/clusterssh/bin_PL/ccon
Generating: /home/ikegami/tmp/clusterssh/bin_PL/crsh
Generating: /home/ikegami/tmp/clusterssh/bin_PL/ctel
Generating: /home/ikegami/tmp/clusterssh/bin_PL/clusterssh_bash_completion.dist
$ for fn in ccon crsh csftp cssh ctel; do printf '%-6s ' "$fn:"; head -n 1 "blib/script/$fn"; done
ccon: #!/home/ikegami/usr/perlbrew/perls/5.26.2t/bin/perl
crsh: #!/home/ikegami/usr/perlbrew/perls/5.26.2t/bin/perl
csftp: #!/home/ikegami/usr/perlbrew/perls/5.26.2t/bin/perl
cssh: #!/home/ikegami/usr/perlbrew/perls/5.26.2t/bin/perl
ctel: #!/home/ikegami/usr/perlbrew/perls/5.26.2t/bin/perl
I didn't bother running ./Build install, whose main task is to copy the files from the staging directory into their final locations. Besides, that part will need to be replaced by your package manager anyway (assuming you're simply placing the contents of the blib directory into your package).
If you somehow need to do it yourself, you could use the following:
find bin -type f \
-exec perl -i -pe'
s/^#!\S*perl\S*/#!$^X/ if $. == 1;
close ARGV if eof;
' {} +
Notes:
Use the perl you wish the scripts to use.
GNU tools assumed; adjust as necessary.
close ARGV if eof; resets the line number ($.) for each file.
eof is different than eof(), and only the former will work here.
The line breaks are optional and may be removed.
I am using the Dist::Zilla module to release and test my module. I am also using Perlbrew. When I run a script using perlbrew that includes my module, the script runs fine:
use strict;
use My::Module;
However, whenever I run dzil test, on a test that just tries to include my module:
#!perl -T
use strict;
use warnings FATAL => 'all';
use Test::More;
plan tests => 1;
BEGIN {
use_ok( 'My::Module' ) || print "Bail out!\n";
}
diag( "Testing My::Module $My::Module::VERSION, Perl $], $^X" );
It fails with this error saying that it can't find the module Mouse (which my module includes):
Error: Can't locate Mouse.pm in #INC (you may need to install the Mouse module) (#INC contains:
/Users/user/github/My/Module/.build/HoKOnIQGYr/blib/lib
/Users/user/github/My/Module/.build/HoKOnIQGYr/blib/arch
/Users/user/perl5/lib/perl5/darwin-thread-multi-2level
/Users/user/perl5/lib/perl5/darwin-thread-multi-2level
/Users/user/perl5/lib/perl5
/opt/local/lib/perl5/vendor_perl/5.16.1/darwin-thread-multi-2level/
/Users/user/perl5/lib/perl5/darwin-thread-multi-2level
/Users/user/perl5/lib/perl5
/opt/local/lib/perl5/vendor_perl/5.16.1/darwin-thread-multi-2level/
/Library/Perl/5.18/darwin-thread-multi-2level /Library/Perl/5.18
/Network/Library/Perl/5.18/darwin-thread-multi-2level
/Network/Library/Perl/5.18
/Library/Perl/Updates/5.18.2/darwin-thread-multi-2level
/Library/Perl/Updates/5.18.2
/System/Library/Perl/5.18/darwin-thread-multi-2level
/System/Library/Perl/5.18
/System/Library/Perl/Extras/5.18/darwin-thread-multi-2level
/System/Library/Perl/Extras/5.18) at
/Users/user/github/My/Module/.build/HoKOnIQGYr/blib/lib/My/Module.pm line 4.
It says that it cannot find Mouse.pm, which I know is located at
/Users/user/perl5/lib/perl5/darwin-2level
I see that for some reason that directory is not located in #INC, which is interesting because if I run this command to print out all the directories in #INC:
perl -e 'print "$_\n" for #INC'
I get:
/Users/user/perl5/lib/perl5/darwin-2level
/Users/user/perl5/lib/perl5
/opt/local/lib/perl5/vendor_perl/5.16.1/darwin-thread-multi-2level/
/Users/user/perl5/perlbrew/perls/perl-5.16.0/lib/site_perl/5.16.0/darwin-2level
/Users/user/perl5/perlbrew/perls/perl-5.16.0/lib/site_perl/5.16.0
/Users/user/perl5/perlbrew/perls/perl-5.16.0/lib/5.16.0/darwin-2level
/Users/user/perl5/perlbrew/perls/perl-5.16.0/lib/5.16.0
.
So when I run perl on the command line then the darwin-2level directory is present in #INC, but whenever I run dzil test it is not. This might not have much to do with Dist::Zilla, since I think Dist::Zilla just creates Makefile.PL and runs make test for you. Could this be because for testing an older version of perl is being required? Like so:
use 5.006;
But even so, some Perlbrew directories are present in #INC during the test such as
/Users/user/perl5/lib/perl5/darwin-thread-multi-2level
Does anyone know how I can make it so I can use the Mouse installation in my perl directory instead of installing a systemwide one? I had a previous error with another module that couldn't be found when I ran dzil test, and that module was in the same directory as Mouse. I was able to fix the issue by installing the module systemwide instead of locally in my home perl5 directory, but I'd prefer to use the Mouse installed by Perlbrew and not mess with my system perl if possible. I am using Perlbrew version 0.73.
You're trying to install it using the wrong perl since you're using dzil installed by a different perl than the one you want to use.
Furthermore, you shouldn't see any of the following in your perlbrewed perl's #INC:
/Users/user/perl5/lib/perl5/darwin-2level
/Users/user/perl5/lib/perl5
/opt/local/lib/perl5/vendor_perl/5.16.1/darwin-thread-multi-2level/ (You perlbrewed perl isn't even threaded!!!)
Let's clean up your environment.
Unset env vars PERL5LIB, PERLLIB, PERL5OPT, PERL_MM_OPT and PERL_MB_OPT. Permanently. Get rid of them in your login scripts, then unset them from the current shell or log back in. (Make a note of what they were as a backup.)
Clear cpan's configuration item makepl_arg. From within cpan,
o conf makepl_arg # Just to see its current value as a backup.
o conf makepl_arg ''
o conf commit
In particular, we want to remove anything that indicates an installation path, including INSTALL_BASE, PREFIX and LIB.
Clear cpan's configuration item mbuildpl_arg. From within cpan,
o conf mbuildpl_arg # Just to see its current value as a backup.
o conf mbuildpl_arg ''
o conf commit
In particular, we want to remove anything that indicates an installation path, including --install_base, --prefix and --lib.
Since you're there, do the following from within cpan:
o conf build_dir_reuse 0
o conf commit
This will restore the setting to its default, which will save you headaches if it was changed.
Install the dependencies.
cpan Dist::Zilla Mouse
At this point, executing which dzil should give
/Users/user/perl5/perlbrew/perls/perl-5.16.0/bin/dzil
If so, you should be good to go.
If not, do hash -r and try which dzil again. (This shouldn't be needed, but just to be sure.)
If still not, provide the output of the following commands:
echo "$PATH"
which cpan
head -n 3 "$( which cpan )"
echo 'o conf' | cpan | grep arg
which dzil
head -n 3 "$( which dzil )"
perl -V # Uppercase "V"
I am trying to build LDV project by following this instructions, and i know nothing about perl.
i am getting the following error while running the test
ldv-task: NORMAL: Calling LDV-core.
Can't locate SOAP/Lite.pm in #INC (#INC contains: /home/acsia/perl5/perlbrew/perls/perl-5.10.0/lib/5.10.0/x86_64-linux /home/acsia/perl5/perlbrew/perls/perl-5.10.0/lib/5.10.0 /home/acsia/perl5/perlbrew/perls/perl-5.10.0/lib/site_perl/5.10.0/x86_64-linux /home/acsia/perl5/perlbrew/perls/perl-5.10.0/lib/site_perl/5.10.0 .) at /home/acsia/Desktop/LDV/consol-tools/ldv-core/ldv-core line 7.
BEGIN failed--compilation aborted at /home/acsia/Desktop/LDV/consol-tools/ldv-core/ldv-core line 7.
output of
perlbrew use
is :EDITED:
Currently using perl-5.22.0
output of
locate SOAP/Lite.pm
is
/usr/local/lib/perl5/site_perl/5.22.0/SOAP/Lite.pm
output of
which perl
is
/usr/local/bin/perl
and the LDV-core file is starting like this by default
#!/usr/bin/perl -w
#
my $instrumnet = 'ldv-core';
use FindBin;
# To prevent meaningless module warnings use this instead of use.
BEGIN { $SIG{'__WARN__'} = sub{}; require SOAP::Lite; SOAP::Lite->import(); $SIG{__WARN__}='DEFAULT'; }
use POSIX ":sys_wait_h";
use XML::Twig;
use IO::Socket::INET;
#use File::MimeInfo;
use File::Basename;
use Cwd qw(abs_path);
etc,... etc....
Thanks for your time...
If LDV-Core isn't yours, you should install SOAP::Lite using your system's package manager. If it's yours, read on.
perlbrew plays with your PATH so that executing perl will execute the desired perl.
But your script explicitly uses /usr/bin/perl, so which perl is currently selected using perlbrew switch or perlbrew use is irrelevant.
Stop overriding the default install location, and stop looking where you shouldn't.
unset PERL_MM_OPT
unset PERL_MB_OPT
unset PERL5LIB
unset PERLLIB
echo -ne 'o conf makepl_arg ""\no conf commit\n' | cpan
echo -ne 'o conf mbuildpl_arg ""\no conf commit\n' | cpan
The first four lines only have a temporary effect. You should stop setting those variables in your login script to make the change permanent.
Install SOAP::Lite in the desired Perl.
perlbrew use perl-5.22.0 # Or perl-5.10.0 or whatever
cpan SOAP::Lite
Fix your script's shebang.
perl -i~ -pe'
next if $. != 1;
s/^#!.*//s;
$_ = "#!$^X\n$_";
' LDV-core
PS — You don't need use FindBin;.
perlbrew perl is a way to install many perl versions in same machine. It is like virtenv in python. Perlbrew allow you to switch between various versions of perl and run perl programs against those versions.
system perl means the default version of perl which mostly come with linux distros. perlbrew changes that version against which program needs to run and your program will start running against different version.
If you are making something which does not require a lot of perl versions it is always better to use one version of perl and run programs against them.
Also if you are using linux distros and do not want to get into cpan and how to install perl modules, best is to search for corresponding libraries against that module and install them. For example in your case i search this way
aptitude search soap | grep perl
This give me two libraries on my ubuntu machine of which one is against this module. Installing them is easy and you can focus on your work rather than on how to install 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"
How do you find the version of an installed Perl module?
This is in an answer down at the bottom, but I figure it important enough to live up here. With these suggestions, I create a function in my .bashrc
function perlmodver {
perl -M$1 -e 'print "Version " . $ARGV[0]->VERSION . " of " . $ARGV[0] . \
" is installed.\n"' $1
}
Most modules (especially ones from The CPAN) have a $VERSION variable:
perl -MSome::Module -le 'print $Some::Module::VERSION'
Why are you trying to get the version of the module? Do you need this from within a program, do you just need the number to pass to another operation, or are you just trying to find out what you have?
I have this built into the cpan (which comes with perl) with the -D switch so you can see the version that you have installed and the current version on CPAN:
$ cpan -D Text::CSV_XS
Text::CSV_XS
-------------------------------------------------------------------------
Fast 8bit clean version of Text::CSV
H/HM/HMBRAND/Text-CSV_XS-0.54.tgz
/usr/local/lib/perl5/site_perl/5.8.8/darwin-2level/Text/CSV_XS.pm
Installed: 0.32
CPAN: 0.54 Not up to date
H.Merijn Brand (HMBRAND)
h.m.brand#xs4all.nl
If you want to see all of the out-of-date modules, use the -O (capital O) switch:
$ cpan -O
Module Name Local CPAN
-------------------------------------------------------------------------
Apache::DB 0.1300 0.1400
Apache::SOAP 0.0000 0.7100
Apache::Session 1.8300 1.8700
Apache::SizeLimit 0.0300 0.9100
Apache::XMLRPC::Lite 0.0000 0.7100
... and so on
If you want to see this for all modules you have installed, try the -a switch to create an autobundle.
VERSION is a UNIVERSAL method of all Perl classes. You can use it to get the module version (if it has been set which it usually has).
Here is a one liner where you only have to add the module name once:
perl -le 'eval "require $ARGV[0]" and print $ARGV[0]->VERSION' Some::Module
There is a less-typing trick, that works provided your module doesn't have something insane like a Unix timestamp as a version number.
perl -MFoo::Bar\ 9999
This works because what it translates to is
use Foo::Bar 9999;
i.e. a version of Foo::Bar that's at least version 9999 or newer.
And what you get is
Foo::Bar version 9999 required--this is only version 1.1.
BEGIN failed--compilation aborted.
(Neat trick I learned from Matt Trout.)
If you are lucky, the module will have a package variable named $VERSION:
$ perl -MCPAN -e 'print "$CPAN::VERSION\n"'
1.9205
This is needed for modules to be distributed on CPAN, but internally developed modules might follow a different convention or none at all.
Thanks for the answers! I've created a function in my .bashrc to easily find the version of a Perl module:
function perlmodver {
perl -M$1 -e 'print $ARGV[0]->VERSION . "\n"' $1
}
Easiest to remember and most robust version for me:
perl -e 'use Search::Elasticsearch; print $Search::Elasticsearch::VERSION;'
Check out the pmtools scripts on CPAN. If you're using a Debian(-based) distro, there's also a handy pmtools package. This includes a script "pmvers" that tells you a module's version. It's quite handy.
It does something similar to the various one-liners folks posted, but it's a bit smarter about error handling, and can give you the version of more than one module at once.
I wrote a small script to report that: perlver.
This is a simple little tool that
tells you what version of a module you
have installed, and where the .pm file
is located. It also ensures the module
can be loaded successfully. It
automatically converts ‘-’, ‘/’, or
‘\’ to ‘::’, so you can use a pathname
or distribution name instead of the
canonical module name.
It assumes that the module defines a $VERSION. If the module doesn't define a $VERSION, it will still tell you where the .pm file is, so you can examine it manually. You can also check several modules at once:
$ perlver CPAN DBD-Pg Getopt::Long
CPAN 1.7602 is
/usr/lib/perl5/5.8.8/CPAN.pm
DBD::Pg 1.49 is
/usr/lib/perl5/vendor_perl/5.8.8/i686-linux/DBD/Pg.pm
Getopt::Long 2.36 is
/usr/lib/perl5/vendor_perl/5.8.8/Getopt/Long.pm
In addition, for modules that use Exporter.pm, you can get this information with this trick:
perl -MSome::Module=99999 -ex
Some::Module version 99999 required--this is only version 1.9205 at ...
For modules that don't use Exporter.pm, a slightly longer trick reports the same information:
perl -e'use Some::Module 99999'
Some::Module version 99999 required--this is only version 1.9205 at ...
We have the system perl (/usr/bin/perl) in Solaris 10, and above solutions are useless. Some of them report "module.pm is not installed", some of them have no output.
Here is the code which is helpful, which can list all modules and their version.
#!/usr/bin/perl
use strict;
use ExtUtils::Installed;
my #modules;
my $installed = ExtUtils::Installed->new();
if (scalar(#ARGV) > 0) {
#modules = #ARGV;
} else {
#modules = $installed->modules();
}
print "Module\tVersion\n";
foreach (#modules) {
print $_ . "\t" . $installed->version($_) . "\n";
}
You can also take a look at App::module::version
$ module-version
The version of App::module::version in /home/yourself/perl5/lib/perl5 is 1.004