如何获得已安装的CPAN模块的列表?
除了尝试
perldoc <module name>
对于任何需要花时间或者通过文件系统并查看目录的CPAN模块,我都不知道我们已经安装了哪些模块。
获得安装的每个CPAN模块的大列表的最简单方法是什么?从命令行或者其他方式。
解决方案
perldoc perllocal
编辑:在CPAN常见问题中有一个(小)更多信息
我喜欢为此使用CPAN'r'命令。我们可以使用旧样式进入CPAN shell:
sudo perl -MCPAN -e shell
或者,在大多数较新的系统上,有一个'cpan'命令,因此该命令将带我们进入shell:
sudo cpan
(通常,我们必须先使用" sudo"将其作为root用户运行,或者使用" su-"成为root用户,然后再运行它,除非我们已设置cpan来允许我们以普通用户身份运行它,但必须以root用户身份安装。如果我们在此计算机上没有root用户,则仍然可以使用CPAN shell来查找此信息,但是我们将无法安装模块,并且第一次使用时可能必须进行一些设置。运行。)
然后,一旦进入cpan shell,就可以使用" r"命令报告所有已安装的模块及其版本。因此,在" cpan>"提示符下,键入" r"。这将列出所有已安装的模块及其版本。使用 '?'以获得更多帮助。
这是在* nix中实现的一种非常hacky的方式,我们会得到一些我们并不真正关心的东西(例如:warnings :: register等),但是它应该为我们提供了每个可通过以下方式访问的.pm文件的列表: perl。
for my $path (@INC) { my @list = `ls -R $path/**/*.pm`; for (@list) { s/$path\///g; s/\//::/g; s/\.pm$//g; print; } }
值得注意的是,perldoc perllocal将仅报告通过CPAN安装的模块。如果有人手动安装模块,它将找不到它们。另外,如果我们有多个人安装模块,并且perllocal.pod受源代码控制,则人可能会错误地解决冲突并破坏列表(例如,这是在工作中发生的)。
遗憾的是,该解决方案似乎是通过File :: Find或者类似方法遍历@INC。但是,不仅可以找到模块,还可以在发行版中找到相关的模块。例如,除了Test :: Harness的实际发行版名称外,它还会报告TAP :: Harness和TAP :: Parser(假设我们具有版本3或者更高版本)。我们可能会将它们与分发名称匹配,并丢弃那些不匹配的名称,但是随后我们可能会丢弃本地构建和安装的模块。
我相信brian d foy的backpan索引工作应该具有将其提交给.pm文件的代码,并且它将尝试推断分布,但是即使这样也有时会失败,因为不一定安装了软件包中的内容(请参阅Devel :: Cover :: Inc为例)。
我们可以尝试使用ExtUtils-Installed,但是只能在.packlist
s中查找,因此它可能会丢失人们手动将东西移到@INC中的模块。
我为一个想在非Shell虚拟主机帐户上作为CGI脚本执行此操作的朋友编写了App-Module-Lister。我们只需简单地获取模块文件,然后将其作为文件名上传,服务器会将其视为CGI脚本。它在标准库之外没有任何依赖项。照常使用它或者窃取代码。
它输出模块及其版本的列表:
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
我一直想将其作为功能添加到cpan
工具中,因此我也会这样做。 [时间流逝]而且,现在我在cpan中有一个-l开关。在发布之前,我还有其他一些事情要做,但是它在github中。如果我们不想等待,可以尝试使用-a开关来创建自动捆绑包,尽管这样会在列表中放置一些Pod。
祝你好运;
要遍历@INC目录树而不使用ls(1)之类的外部程序,可以使用File :: Find :: Rule
模块,该模块具有一个不错的声明性接口。
另外,如果以前的Perl版本包含相同的模块,则希望过滤掉重复项。执行此操作的代码如下所示:
#! /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}++; } }
运行结束时,我们还将所有模块名称作为%seen哈希中的键。该代码可以进行修改,以将规范的文件名(在$ file中给出)保存为键的值,而不是所看到的次数。
这可以在Perl FAQ中得到解答,可以通过安装" perldoc -q"快速找到答案。简而言之,可以归结为使用ExtUtils :: Installed
或者使用File :: Find
,这两个线程的变体已在本线程中进行了介绍。
我们还可以找到FAQ条目"如何查找系统上安装了哪些模块?"。在perlfaq3中。我们可以通过查看perlfaq来查看所有常见问题解答的列表
可以在Perl FAQ列表中找到答案。
我们应该浏览Perl随附的出色文档
perldoc perltoc
我昨天才写了一个perl脚本来完成这个任务。该脚本使用'::'作为分隔符返回@INC中安装的perl模块的列表。使用-调用脚本
perl perlmod.pl
或者
perl perlmod.pl <module name> #Case-insensitive(eg. perl perlmod.pl ftp)
到目前为止,由于我在递归软链接方面遇到问题,该脚本会跳过当前目录('。'),但我们可以通过更改第17行中的grep函数从
grep { $_ !~ '^\.$' } @INC
只是,
@INC
脚本可以在这里找到。
试试man perllocal
或者perldoc perllocal
。
这是另一个列出所有已安装的.pm文件的命令行工具:
查找与正则表达式匹配的已安装Perl模块
- 可移植(仅使用核心模块)
- 缓存选项可加快查找速度
- 可配置的显示选项