【问题标题】:How do I get a list of installed CPAN modules?如何获取已安装 CPAN 模块的列表?
【发布时间】:2010-09-12 00:57:55
【问题描述】:

除了尝试

perldoc <module name>

对于我喜欢的任何 CPAN 模块或通过文件系统查看目录,我都不知道我们安装了哪些模块。

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

【问题讨论】:

  • 我可以建议使用pmtools,尤其是接受正则表达式的pminst
  • perl-pmtools 是你的好工具。
  • 您想知道安装了哪些模块,或者安装了哪些发行版?
  • 我发现 cpan -l 在 Windows 上对我自己很有用。
  • 这可能有用:instmodsh

标签: perl cpan


【解决方案1】:

Perl FAQ 中对此进行了解答,可以通过perldoc -q installed 快速找到答案。简而言之,它归结为使用 ExtUtils::Installed 或使用 File::Find,这两种变体都已在本线程前面介绍过。

您还可以在 perlfaq3 中找到常见问题解答条目 "How do I find which modules are installed on my system?"。您可以通过查看perlfaq查看所有常见问题解答列表

【讨论】:

  • 这比 OP 要求的要多得多,几乎没用。
  • cpan -l 正在对我运行它的任何目录进行递归搜索。有没有办法从该命令行传递ExtUtils::Installed 构造函数的skip_cwd 选项?
  • FAQ 说要使用 cpan -l,但这在 RHEL6 上不起作用,/usr/bin/cpan -l 会抛出错误 Unknown option: l
  • $ perldoc perllocal | grep 模块 $ perldoc perllocal | grep -E '版本|模块'
  • 使用 perldoc -t perllocal 获取纯文本输出,否则由于嵌入 ctrl 字符,grep 可能无法工作
【解决方案2】:
perldoc perllocal

编辑:CPAN FAQ 中有(少量)更多信息

【讨论】:

  • 感谢您提供常见问题解答链接。不幸的是,并非我所知道的所有已安装模块都返回了。 Date::Calc 甚至没有出现在那里。
  • 我收到了No documentation found for "perllocal".
【解决方案3】:

perldoc -q installed

声称cpan -l 可以解决问题,但它对我不起作用。另一种选择:

cpan -a

确实会列出一个不错的已安装软件包列表,并且具有将它们写入文件的不错的副作用。

【讨论】:

  • 作为记录,cpan -l 可以工作(或者使用 CPAN v2.05 为我工作)。 cpan -a确实更漂亮。
  • 我刚刚使用cpan -l | grep packageName 根据 perldoc 中的建议找到我需要的内容。
【解决方案4】:

值得注意的是 perldoc perllocal 只会报告通过 CPAN 安装的模块。如果有人手动安装模块,它不会找到它们。此外,如果您有多个人安装模块并且 perllocal.pod 处于源代码控制之下,人们可能会错误地解决冲突并破坏列表(例如,这在工作中发生过)。

遗憾的是,解决方案似乎是使用 File::Find 或类似的东西遍历 @INC。但是,这不仅会找到模块,还会在分发中找到相关的模块。例如,它会报告 TAP::Harness 和 TAP::Parser 以及 Test::Harness 的实际分发名称(假设您有版本 3 或更高版本)。您可能会将它们与分发名称匹配并丢弃那些不匹配的名称,但是您可能会丢弃本地构建和安装的模块。

我相信 brian d foy 的 backpan 索引工作应该有代码在 .pm 文件中处理它,它会尝试推断分布,但即使这样有时也会失败,因为不一定安装包中的内容(参见开发::Cover::Inc 为例)。

【讨论】:

  • 我认为我不需要为那个拿出 BackPAN 目录枪。像我对 Test::Prereq 所做的那样,通过它在 02packages 中找到的发行版来折叠它可能就足够了。不过,这比仅仅列出模块文件要复杂一些,而且目录还不能处理这个问题。
  • 从初步测试(在我放置的一些目录中执行“make -n install”),任何基于 MakeMaker 的模块的“make install”步骤都会更新 perllocal。它并不特定于直接通过 CPAN 安装。
  • 我认为 Dist::Surveyor 仍然是回答“该库中安装了哪些发行版?”问题的最佳工具。有关详细信息,请参阅this presentationgit repo 中有一个易于使用的 fatpacked 版本。
【解决方案5】:
$ 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"

【讨论】:

  • 这很适合我们这些没有安装 cpan 的人。
  • 真正被低估的答案。这也适用于 RHEL 发行版。
  • 我得到了:No documentation found for "perllocal".
  • 运行时间比我预期的要长(在我的机器上大约 20 秒左右),但它运行完美!很好的答案。
【解决方案6】:

您可以尝试ExtUtils-Installed,但它只在.packlists 中查找,因此它可能会错过人们手动将内容移至@INC 的模块。

我写了App-Module-Lister 给一个朋友,他想在非 shell 虚拟主机帐户上将其作为 CGI 脚本执行。您只需获取模块文件并将其作为文件名上传,您的服务器会将其视为 CGI 脚本。它在标准库之外没有依赖项。按原样使用或窃取代码。

它输出模块列表及其版本:

领带::循环 1.15 领带::IxHash 1.21 领带::切换 1.07 领带::ToObject 0.03 时间::CTime 99.062201 时间::DaysInMonth 99.1117 时间::纪元 0.02 时间::模糊 0.34 时间::JulianDay 2003.1125 时间::解析日期 2006.0814 时间::时区 2006.0814

我一直打算将此作为功能添加到cpan 工具中,所以我也会这样做。 [时间流逝] 而且,现在我在cpan 中有一个-l 开关。在发布之前,我还有其他一些事情要做,但是it's in github。如果您不想等待,可以尝试使用-a 开关来创建自动捆绑,尽管这会将一些 Pod 放在列表中。

祝你好运;

【讨论】:

    【解决方案7】:

    这里有一个脚本可以解决问题:

    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
    

    【讨论】:

    • 在 RHEL 6.9 下,此脚本仅打印以下内容:Perl - 5.10.1 未列出模块。
    【解决方案8】:

    我喜欢为此使用 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”。这将列出所有已安装的模块及其版本。采用 '?'获得更多帮助。

    【讨论】:

    • 实际上 'r' 为您提供了重新安装建议 - 即您安装的所有模块都具有较新版本的 CPAN。除非您的安装非常过时,否则这不是一个完整的列表。
    • 我的“r”总是几乎没有报告,因为我强制升级。这让我想起了……我今天还没有升级。
    • -r 重新编译东西。要获取列表,请尝试 -a 或下载最新的源代码并使用新的 -l 开关,仅为此答案添加。 :)
    • 这里为什么是sudo?这是完全没有必要的。
    • 注意 'cpan' 的 '-r' 命令行参数和 cpan shell 中的 'r' 命令之间的区别 :)
    【解决方案9】:
    perl -MFile::Find=find -MFile::Spec::Functions -Tlwe 'find { wanted => sub { print canonpath $_ if /\.pm\z/ }, no_chdir => 1 }, @INC'
    

    【讨论】:

    • 这非常好,因为它清楚地显示了每个 *.pm 模块的完整路径。你可能会看到很多重复...
    【解决方案10】:

    在 Linux/Unix 上,我使用这个简单的命令:

    perl -e 'print qx/find $_ -name "*.pm"/ foreach ( @INC );' 
    

    它会扫描@INC 中的所有文件夹并查找任何 *.pm 文件。

    【讨论】:

    • 谢谢!非常有用。
    • 谢谢!这可能是我学过的最简洁的表达方式。
    【解决方案11】:

    这是在 *nix 中执行此操作的一种非常老套的方法,您会得到一些您并不真正关心的东西(例如: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; } }

    【讨论】:

    • 这不会给他他想要的。它不会按照它们所属的发行版对相关文件进行分组,它会列出来自 Perl 本身的所有核心 *.pm 文件。
    【解决方案12】:

    您可以在终端中使用instmodsh 命令获取系统中安装的 perl 模块列表。它会询问您三个选项以增强输出:

       l            - List all installed modules
       m <module>   - Select a module
       q            - Quit the program
    

    【讨论】:

      【解决方案13】:

      试试下面的命令

      instmodsh

      【讨论】:

      • 最简单的答案。在我们古老的 Debian 6 服务器上运行良好。
      【解决方案14】:

      所有无法安装 perldoc 或其他模块,并想知道哪些模块可用(CPAN 或其他)的人,以下适用于 linux 和 Mingw32/64:

      grep -RhIP '^package [A-Z][\w:]+;' `perl -e 'print join " ",@INC'` | sed 's/package //' | sort | uniq
      

      是的,很乱。是的,它可能报告的比你想要的多。但是,如果将其通过管道传输到文件中,则可以轻松检查,例如,存在哪些 dbm 接口:

       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;
      

      这就是我最终出现在此页面上的原因(失望)

      (我意识到这并不能完全回答 OP 的问题,但我将它发布给任何最终出于同样原因来到这里的人。这就是堆栈的问题***几乎不可能找到问题你问的是,即使它存在,但 stack*** 几乎总是谷歌的热门!)

      【讨论】:

      • 这对我有用。感谢您发布此信息。在我没有太多权限安装/更新任何依赖项的环境中,我需要这个。
      【解决方案15】:

      这是@JamesThomasMoon1979 重写的单行脚本

      perl -MExtUtils::Installed -e '$i=ExtUtils::Installed->new(); 
            print "$_ ".$i->version($_)."\n" for $i->modules();'
      

      【讨论】:

        【解决方案16】:

        答案可以在Perl FAQ list找到。

        你应该浏览一下 Perl 附带的优秀文档

        perldoc perltoc
        

        【讨论】:

          【解决方案17】:

          试试man perllocalperldoc perllocal

          【讨论】:

            【解决方案18】:

            我昨天写了一个 perl 脚本来做这件事。该脚本使用 '::' 作为分隔符返回安装在 @INC 中的 perl 模块列表。使用 - 调用脚本 -

            perl perlmod.pl
            

            perl perlmod.pl <module name> #Case-insensitive(eg. perl perlmod.pl ftp)
            

            到目前为止,脚本跳过了当前目录('.'),因为我遇到了递归软链接的问题,但是您可以通过更改第 17 行中的 grep 函数来包含它

              grep { $_ !~ '^\.$' } @INC
            

            只是,

            @INC
            

            脚本可以在here.找到

            【讨论】:

              【解决方案19】:

              这是另一个列出所有已安装 .pm 文件的命令行工具:

              Find installed Perl modules matching a regular expression

              • 便携(仅使用核心模块)
              • 缓存选项可加快查找速度
              • 可配置的显示选项

              【讨论】:

                【解决方案20】:

                要在不使用 ls(1) 之类的外部程序的情况下遍历 @INC 目录树,可以使用 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 中给出)保存为键的值,而不是看到的次数。

                【讨论】:

                  【解决方案21】:

                  以下内容对我有用。

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

                  【讨论】:

                    【解决方案22】:

                    Perl 食谱包含脚本“pmdesc”的多次迭代,可以满足您的需求。 谷歌搜索“Perl Cookbook pmdesc”,你会发现articles on other Q&A Sites、网上的几个代码清单、解决方案的讨论,甚至some refinements

                    【讨论】:

                      【解决方案23】:

                      这是一个 Perl 单行代码,它将打印出已安装模块的列表:

                      perl -MExtUtils::Installed -MData::Dumper -e  'my ($inst) = ExtUtils::Installed->new(); print Dumper($inst->modules());'
                      

                      只要确保您已安装 Data::Dumper。

                      【讨论】:

                      • 这仅列出了大约 15 个 perl 模块,而不是 'cpan -l' 列出的 5945 个。
                      【解决方案24】:
                      cd /the/lib/dir/of/your/perl/installation
                      perldoc $(find . -name perllocal.pod)
                      

                      Windows 用户只需执行 Windows 资源管理器搜索即可找到它。

                      【讨论】:

                        【解决方案25】:

                        试试“perldoc -l”:

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

                        【讨论】:

                          【解决方案26】:

                          当您输入 Perl 脚本时,所有已安装的模块都以 .pm 文件的形式出现在 @INC 的文件夹下,因此一个小的 bash 脚本将为您完成这项工作:

                          #!/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
                          

                          【讨论】:

                          • 为什么不呢? find `perl -le'print for@INC'` -name '*.pm'
                          【解决方案27】:

                          对于 Linux,最简单的获取方法是,

                          dpkg -l | grep "perl"
                          

                          【讨论】:

                          • OP 要求提供系统中安装的 CPAN (perl) 模块的列表,而不是系统中是否安装了 perl(OP 都没有告诉我们 apt 是否可用)
                          • 我不是 perl 专家,但我已经看到通过上述命令安装了 perl 模块。这里可能不是完美的答案。
                          • @YasiruG 它只列出那些通过包安装的;这在任何安装中都是少数。其中大部分是通过 CPAN 安装的。
                          【解决方案28】:

                          这对我有用

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

                          【讨论】:

                          • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation would greatly improve its long-term value 通过展示为什么这是一个很好的解决问题的方法,并将使其对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。
                          【解决方案29】:

                          这就是我的工作:perl -M{cpan_module}
                          如果您没有收到任何错误,则很有可能安装了该模块。

                          【讨论】:

                          • 我不相信这能回答这个问题。使用这个建议,可能需要很长时间才能逐个模块地检查哪些模块已安装。
                          猜你喜欢
                          • 2013-09-24
                          • 2011-02-06
                          • 2016-07-08
                          • 2018-06-19
                          • 2014-12-06
                          • 2013-11-04
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多