如何通过 `cpan` 卸载已安装的 Perl 模块?

89
我正在使用在用户空间内运行的Perl(未通过root安装),并通过命令行cpan安装模块。我想知道是否有一种简单的方法来删除模块,而不必删除单个文件。
我在互联网上搜索了这个问题,并找到了一些答案,但我找到的答案似乎要么讨论使用Perl程序包管理器(专门针对Microsoft Windows),否则是特定于操作系统(BSDpan),建议使用cpanplus(我曾经有过几次糟糕的经历),或者是指向一个失效的链接,如下所示:http://www.cpan.org/misc/cpan-faq.html#How_delete_Perl_modules
我的问题具体是是否有一种清洁的方法来删除通过cpan安装的模块。

38
你真的想不出任何理由想要从系统中删除任何Perl模块吗? - user181548
5
我需要删除一些模块,以便在我的2GB Raspberry Pi上腾出空间。 - Ray
8
一个显而易见的原因是测试代码,以检测在启动期间最终用户是否安装了所需的Perl模块。这就是我现在所处的位置。我想我必须启动一个干净的虚拟机来运行那个测试。 - AlwaysLearning
6
回答技术问题时,解释“为什么”并不是必要的。 - felwithe
3
另一个原因(尽管原始评论似乎已被删除)- 您通过 cpan 安装了一个模块,然后发现它在分发包中可用。 - Richlv
显示剩余3条评论
6个回答

76
  1. 从CPAN安装App::cpanminus(使用: cpan App::cpanminus).
  2. 输入cpanm --uninstall Module::Name (注意 "m") 以使用cpanminus卸载模块。

这应该可以工作。


似乎使用cpan App::cpanminus安装App::cpanminus模块并不会安装任何cpanm工具,如果我在OS X上键入cpanm --uninstall Module::Name,则会出现-bash: cpanm: command not found。我有什么遗漏的吗? - tonix
@tonix:检查它的位置是否在你的 $PATH 中。 - reinierpost
这是一个旧评论。你的意思是使用 find . -name '*cpanm' | grep -E 'cpanm' 吗? - tonix
在 Mac 上,您不需要使用“查找”功能。使用 Spotlight 的 mdfind cpanm 更快。 - Armand
4
我使用 Perl v5.22.1 运行了命令 sudo cpan install "DateTime::Format::Builder",一切正常。然后我运行了命令 cpanm --uninstall "DateTime::Format::Builder" 来卸载该模块,但出现了错误信息 "is not found in the following directories and can't be uninstalled"。这些目录是:/usr/local/lib/x86_64-linux-gnu/perl/5.22.1/usr/local/share/perl/5.22.1。我使用命令 sudo apt install cpanminus 安装了 cpanm (版本为 v1.7040)。有什么想法吗? - Pablo Bianchi
显示剩余2条评论

49

你做不到。我的CPAN客户端没有此功能。我们在本周末的Perl QA工作坊上讨论了如何实现这样的功能,但通常由于Ether提到的所有原因,这很难。


Python在setuptools上也遇到了同样的问题。通过使用(或在安装时生成)包元数据,其中包括文件列表,这个问题在pip中得以解决。 - ivan_pozdeev
Python并没有真正解决那个问题。人们一直在谈论用Perl做同样的事情,但这不可靠,因为模块可能不会提供它们的元数据。 - brian d foy
2023年:过去13年里这种情况没有改变吗?是否有更近期的信息来源?您能否在此帖子中添加一个___附录(2023):___? - jubilatious1
事情并没有改变,现在的答案和过去一样好。 - brian d foy

32
一般来说,CPAN模块没有特定的“卸载”机制。但您可以尝试在模块解压缩的原始目录中运行make uninstall命令(通常位于/root/.cpan~/.cpan下),因为某些软件包在其安装脚本中包含此指令。(但是,由于您已将模块安装到本地(非根)库目录中,您还可以选择删除整个目录并重新安装其他要保留的所有内容。)
很多时候,您可以简单地删除perllib中的A/B.pm文件(对于A::B模块),这至少会使该模块无法使用。大多数模块还包含要安装的文件列表(称为“清单”),因此如果您能找到它,就会知道哪些文件可以删除。
但是,这些方法都无法解决安装为依赖项的任何模块。无法自动判断是否有其他内容依赖于该模块,因此一旦确定,您必须手动卸载它。
卸载模块的困难之处是许多Perl开发人员正在转向使用版本控制系统来跟踪安装 - 例如,请参见brian d foy的文章作为他即将出版的书的补充,其中讨论了使用git进行软件包管理的内容。

3
那不是书中的摘录,而是额外的内容,你在《Effective Perl Programming》中找不到它。 - brian d foy
1
“没有好的(自动化)方法可以知道是否有其他内容依赖于该模块” - 为什么无法知道? - user181548
1
@brian:啊,抱歉,我误解了那个网站的性质! - Ether

25

2
我想真正的问题是:从你的Perl目录中删除它是否有什么问题? - felwithe

19

更新于2013年:这段代码已经过时。请点赞 bsb最新的答案


我不经常需要卸载模块,但基于.packlist文件的方法到目前为止从未让我失望。

use 5.010;
use ExtUtils::Installed qw();
use ExtUtils::Packlist qw();

die "Usage: $0 Module::Name Module::Name\n" unless @ARGV;

for my $mod (@ARGV) {
    my $inst = ExtUtils::Installed->new;

    foreach my $item (sort($inst->files($mod))) {
        say "removing $item";
        unlink $item or warn "could not remove $item: $!\n";
    }

    my $packfile = $inst->packlist($mod)->packlist_file;
    print "removing $packfile\n";
    unlink $packfile or warn "could not remove $packfile: $!\n";
}

2

在安装任何模块时,它主要将相应的.pm文件放置在各自的目录中。因此,如果您只想为某些测试目的或暂时删除模块,则最好使用perldoc -l <MODULE>查找存储模块的路径,然后将该模块简单地从那里移动到其他位置。这种方法也可以尝试作为更永久的解决方案,但我不知道是否存在任何负面后果,因为我主要用于测试。


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