我该如何找出Perl模块的安装位置?

62

如何通过名称获取已安装的Perl模块的路径,例如Time::HiRes?

我之所以需要这个是因为我必须在SGE Grid Engine系统的不同节点上运行我的perl脚本。有时候,甚至要使用其他用户名运行。

我可以使用CPAN.pm为自己安装软件包,但对于其他用户来说,如果没有在文件夹上执行chmod 666命令,就很难安装。


1
你为什么想知道这个?你是需要在另一个程序中使用它还是只是想在命令行上看到它? - brian d foy
1
目前最简单的方法是在Ivan的回答中描述的,即使用perl -d,然后输入M - Will Sheppard
10个回答

103

perl -MTime::HiRes -e 'print $INC{"Time/HiRes.pm"}' 或者 perldoc -l Time::HiRes

这段代码可以用来查看Time::HiRes模块是否已经安装在您的计算机上,如果输出了文件路径,则表示该模块已经成功安装。

3
perldoc仅适用于已设置好的环境。 第一个方法适用于所有情况,但是重复输入名称有点烦人。 - Galaxy
如果定位数据库由于任何原因都没有它,可以使用“find /usr/ -path '*/Time/HiRes.pm'”来查找。 - Svante
2
这并不告诉你Perl正在哪里寻找文件。例如,我的Perl模块在~/perl/install中。 - jrockway
好的,在我的情况下,用户文件都在NFS路径中,而locate命令只会排除NFS文件系统。 由于该系统上的PERL5LIB有点长,因此使用find命令不是一个好方法。 - Galaxy
对于Windows系统,可能需要在外部使用双引号,在内部使用单引号。如果按照给定的命令出现错误:Can't find string terminator "'" anywhere before EOF at -e line 1.,这是在Windows 7上发生的。命令:perl -MTime::HiRes -e "print $INC{'Time/HiRes.pm'}" 是有效的。 - Skurfur
perldoc 仅适用于已设置的模块。我想知道什么是设置好的模块。这两个命令都适用于使用 pacmancartoncarton exec ...)安装的模块。此外,您可以执行 perl -MTime::HiRes -e 'for my $k (keys %INC) { print "$k: $INC{$k}\n"; }' - x-yuri

34

大多数情况下,我使用perldoc来获取位置:

$ perldoc -l Module

你也可以使用随Perl一起提供的cpan工具获取模块详细信息:

$ cpan -D Time::HiRes
Time::HiRes
-------------------------------------------------------------------------
    High resolution time, sleep, and alarm
    J/JH/JHI/Time-HiRes-1.9719.tar.gz
    /usr/local/perls/perl-5.10.0/lib/5.10.0/darwin-2level/Time/HiRes.pm
    Installed: 1.9711
    CPAN:      1.9719  Not up to date
    Andrew Main (Zefram) (ZEFRAM)
    zefram@fysh.org

它甚至可以在你没有安装的模块上运行:

$ cpan -D Win32::Process
Win32::Process
-------------------------------------------------------------------------
    Interface to Win32 Process functions
    J/JD/JDB/Win32-Process-0.14.tar.gz
    Installed: 
    CPAN:      0.14  Not up to date
    Jan Dubois (JDB)
    jand@activestate.com

我认为我可能需要像svn一样的XML选项。


1
但是,CPAN 上的所有东西都有。 - Galaxy
2
我不理解你的评论。 - brian d foy
6
如果您编写了一个名为FOO::Bar的包,并将其放入PERL5LIB中,会发生什么? - Galaxy

21

注意:本解决方案建议使用您必须进行下载的(自编写的)实用程序。虽然它提供了我认为有用的功能,但首先安装第三方解决方案并非对所有人都是可行的选择


我创建了whichpm,一个跨平台命令行界面(Linux、macOS、Windows),通过模块(软件包)名称定位已安装的Perl模块,并可选地报告有关它们的信息,包括检测意外重复项。

示例

# Locate the Data::Dumper module.
$ whichpm Data::Dumper
/usr/lib/perl/5.18/Data/Dumper.pm

# 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

# Locate the Data::Dumper module and open it in your system's default text
# editor.
$ whichpm -e Data::Dumper

# Look for accidental duplicates of the Foo::Bar module.
# Normally, only 1 path should be returned.
$ whichpm -a Foo::Bar
/usr/lib/perl/5.18/Foo/Bar.pm
./Foo/Bar.pm

# Print the paths of all installed modules.
$ whichpm -a

安装

先决条件:已安装LinuxmacOSWindows操作系统,且安装了Perl v5.4.50或更高版本

从npm registry安装

如果已经安装了Node.jsio.js,可以执行以下命令来安装该软件包

[sudo] npm install whichpm -g

手动安装(适用于 macOS 和 Linux)

  • 下载命令行界面 (CLI),并将其保存为 whichpm
  • 使用命令 chmod +x whichpm 使其可执行。
  • 将其移动或创建符号链接到 $PATH 中的文件夹中,例如 /usr/local/bin(OSX)或 /usr/bin(Linux)。

谢谢,@Galaxy。你提供的代码确实很方便。这个解决方案增加了以下功能:在OS X和Windows上检测大小写不一致的名称、核心模块状态、查找重复项以及直接打开模块进行编辑。 - mklement0

12

如果需要查找脚本实际使用了哪些模块,可以使用Perl调试器的M命令:

[ivan@server ~]$ perl -d your_script.pl
...
调试程序已终止。使用q退出或R重新启动, 使用o inhibit_exit避免在程序终止后停止, h q、h R或h o以获取其他信息。
DB M 'AutoLoader.pm' => '5.60来自/usr/lib/perl5/5.8.8/AutoLoader.pm' 'Carp.pm' => '1.04来自/usr/lib/perl5/5.8.8/Carp.pm' ...

这将有助于在模块具有相同名称但位于不同文件夹的情况下进行查找。


4
这是最佳答案,因为它非常简单,不需要下载任何额外的软件。 - Will Sheppard

4
我刚刚找到了另一个相关的网站:http://www.perlmonks.org/?node_id=568730
#!/bin/sh

echo 'print map { sprintf( "%20s : %s\n", $_, $INC{$_} ) } sort keys %INC; print "\n'$1' version : $'$1'::VERSION\n\n"' | perl "-M$1" 

当你运行perl -MSTH::STH时,脚本会打印出%INC中的所有内容。
$ whichpm CGI       
              CGI.pm : /System/Library/Perl/5.8.6/CGI.pm
         CGI/Util.pm : /System/Library/Perl/5.8.6/CGI/Util.pm
             Carp.pm : /System/Library/Perl/5.8.6/Carp.pm
         Exporter.pm : /System/Library/Perl/5.8.6/Exporter.pm
         constant.pm : /System/Library/Perl/5.8.6/constant.pm
         overload.pm : /System/Library/Perl/5.8.6/overload.pm
           strict.pm : /System/Library/Perl/5.8.6/strict.pm
             vars.pm : /System/Library/Perl/5.8.6/vars.pm
         warnings.pm : /System/Library/Perl/5.8.6/warnings.pm warnings/register.pm : /System/Library/Perl/5.8.6/warnings/register.pm

CGI version : 3.05

1
如果你只想要版本号,最简单的方法可能是输入 perl -MYour::Module\ 999。如果版本号小于999,则会打印出来。 - jrockway
1
好的,但如果你不能解释那段代码在做什么,就没有赞了。 - Ether
3
这个问题用Perl不是更容易吗?而不用在它周围包装一个shell脚本? - Chris Lutz

3

我喜欢使用V模块。

只需从CPAN安装它或在Debian或Ubuntu上安装libv-perl包即可。

然后像这样使用它:

$ perl -MV=DBI
DBI
    /Users/michiel/.plenv/versions/5.24.0/lib/perl5/site_perl/5.24.0/darwin-2level/DBI.pm: 1.636

其他输出示例:

$ perl -MV=Time::HiRes
Time::HiRes
    /usr/lib/perl/5.18/Time/HiRes.pm: 1.9725

2

Perldoc -l 对我有用

perldoc -l "File::Find"
/opt/perl_32/lib/5.8.8/File/Find.pm

1
似乎最简单的方法是 perldoc -l Time::HiRes
如果由于某些原因无法使用该功能,则可以采用实用解决方案:
步骤1:在您的脚本中实例化该模块...
#! /usr/bin/perl -w
use Time::HiRes();
new Time::HiRes();

第二步:使用Perl图形调试器执行脚本...
export PERL5LIB=$PERL5LIB:~/perl ## tell perl where to look for "Devel"/"ptkdb.pm"
perl -d:ptkdb (yourscript.pl)

步骤三:进入新的调用。
完整模块路径名将显示在调试器窗口的标题栏上。

另一种可能有用的方法是搜索$PERL5LIB中的所有文件夹。


1
perldoc -l 命令无法显示没有 pod 的自制 .pm 文件。 - Galaxy
@Galaxy 如果你不知道自己的自制 .pm 文件在哪里,那你是怎么引用它们的呢? - felwithe
1
我设置了几个PERL5LIB位置,我需要知道哪一个适用于那个pm文件。 - Galaxy

0
为了扩展@Ivan的答案,使其无需安装其他软件,以下将使用Perl调试器来查找特定模块(或模块):
perl -de 'use <Module Name>;'

例如:
perl -de 'use DBD::Oracle;'

输出:

Loading DB routines from perl5db.pl version 1.37
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

DBD::Oracle::CODE(0x27f81d8)(/usr/local/lib64/perl5/DBD/Oracle.pm:113):
113:            $ENV{PERL_BADFREE} = 0;
  DB<1> q

对我来说,它显示“调试程序已终止”。为什么它会进入“use”中? - x-yuri

0
在OSX中,您可以使用:

perl -e 'print join("\n",@INC)'

结果应该是您的lib位置。
然后在Perl代码中添加此代码:
use lib '/your/folder/location/to/lib';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接