如何在命令行中检查Perl模块是否已安装?

76

我尝试检查一下系统中是否已安装XML::Simple模块。

perl -e 'while (<@INC>) { while (<$_/*.pm>) { print "$_\n"; } }'

上述一行代码用于列出我系统中安装的所有模块。然而,它没有列出XML模块。

但是,下面的代码可以正常执行。

perl -e "use XML::Simple "

可能是什么问题?


@Sinan:你改变了问题的意思。我认为原来的问题是如何找出模块安装的位置,现在变成了是否安装了一个模块。 - innaM
我真的不知道。但考虑到当前的问题,你的答案到目前为止是最好的。也许Chells能给我们一些启示。 - innaM
1
@Sinan:为什么你把标签从perl-module改成perl-modules,后者几乎没有使用? - Greg Bacon
http://theunixshell.blogspot.in/2012/12/check-for-installed-modules-in-perl.html - Vijay
11个回答

112

您可以通过以下步骤检查模块的安装路径:

perldoc -l XML::Simple

你的一行代码存在问题,它没有递归遍历目录/子目录。因此,你仅仅得到了实际模块名称作为输出。


1
@Manni:应该可以与大多数模块(来自CPAN)一起使用,因为它们都有文档记录。 - Alan Haggai Alavi
1
有些文档十分详细,它们的文档在它们自己的 .pod 文件中。这是一个很好的技巧,在大多数情况下都能很好地工作,只有一点小问题。 - innaM
3
只有当模块包含 Pod 时,这才起作用。虽然奇怪但却是真实的。 - brian d foy
2
你应该使用-lm而不是-l。它们基本相同,只是-lm也适用于没有POD的模块。 - ikegami
2
不幸的是,在我的服务器上未安装perldoc:“您需要安装perl-doc软件包才能使用此程序。” - user4035
显示剩余2条评论

54

简单粗暴:

$ perl -MXML::Simple -e 1

3
如果你想要版本的话,大多数人都说“perl -MModule\ 999”。 - jrockway
致匿名编辑者:正确的方式是 perl -MDigest::SHA -e 1 而不是 perl -Digest::SHA -e 1 - Sinan Ünür
2
我经常使用这个,尽管我通常会执行-e "print( \"got it\n\" )" - Lucas
这是我喜欢的:)。 - squiguy
2
这个答案更适合在 shell 函数中使用:if ! perl -M$module -e 1 2>/dev/null; then - Stuart Cardall
如果我们使用cpan -l来验证模块,这将有助于丢弃任何后续生成的警告/错误。 - Prashanth

22
$ perl -MXML::Simple -le 'print $INC{"XML/Simple.pm"}'

根据 perlvar 关于 %INC 的说明:

  • %INC

%INC 哈希表包含通过 do, require, 或 use 操作符所包含的每个文件的条目。键是您指定的文件名(模块名称转换为路径名),值是找到该文件的位置。require 操作符使用此哈希表来确定是否已经包含了特定文件。

如果文件是通过钩子(例如,子例程参考,请参见 require 中这些钩子的描述)加载的,则默认情况下将此钩子插入到 %INC 中以替代文件名。但请注意,钩子可能已经自行设置了 %INC 条目,以提供一些更具体的信息。


19
例如,要检查DBI模块是否已安装,请使用以下方法:
perl -e 'use DBI;'

如果未安装,您将看到错误。 (来自http://www.linuxask.com

12

如果你想快速检查一个模块是否已安装(至少在Unix系统上,使用Bash作为shell),请将以下内容添加到你的.bashrc文件中:

alias modver="perl -e\"eval qq{use \\\$ARGV[0];\\\\\\\$v=\\\\\\\$\\\${ARGV[0]}::VERSION;};\ print\\\$@?qq{No module found\\n}:\\\$v?qq{Version \\\$v\\n}:qq{Found.\\n};\"\$1"

然后您可以:
=> modver XML::Simple
No module found

=> modver DBI
Version 1.607

我喜欢这个。谢谢。 - Anthony
3
这个也适用于玉米面包。但是说真的,你需要找一个爱好。 - DS.

9
您所做的并不是递归进入目录,而仅仅是列出了@INC目录下根目录中的模块。
模块XML::Simple将存储在@INC路径之一下的XML/Simple.pm中。
他上面所说的是查找特定模块的方法。 CPAN解释了如何找到所有模块,请参见如何找到已安装的模块

3

while (<@INC>)

这段代码将 @INC 中的路径连接成一个由空格分隔的字符串,然后在该字符串上调用 glob() 函数,除非有文件通配符,否则会遍历由空格分隔的组件。

如果 @INC 中包含带有空格、\、[]、{}、*、? 或 ~ 的路径,则此方法可能不太适用。因此,使用以下安全替代方案似乎没有理由:

for (@INC)

3

如果您在Windows下运行ActivePerl

  • C:\>ppm query * 获取所有已安装模块的列表

  • C:\>ppm query XML-Simple 检查是否已安装XML::Simple


0

我相信你的解决方案只会查找@INC数组中每个目录路径的根目录。你需要递归的东西,比如:

 perl -e 'foreach (@INC) {
    print `find $_ -type f -name "*.pm"`;
 }'

这段代码没有正确引用 $_;如果它包含空格,它会在单词处中断;如果它包含 ;,它会破坏命令(shell注入)- 使用 String::ShellQuote 或不太优化的解决方案 quotemeta 内置函数来引用。 - amphetamachine

0
你可以使用命令。点击这里查看。
在你的情况下,使用命令。
它会告诉你模块安装的位置以及是否是最新版本。

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