linux - 使用包管理器时如何管理 Perl 模块?

一个 recent question在这里,我开始思考了。

在我尝试过的大多数 Linux 发行版上,一些 Perl 模块可以通过包管理器获得。其他人,当然不是。在很长一段时间里,每当我需要安装一些 CPAN 模块时,我都会使用我的包管理器来确定一个包是否可用,并在它可用时安装它。

明显的优势是,只要有新版本的软件包可用,您就可以更新模块。

但是,当模块不以预打包形式提供并且该模块存在依赖项时,您就会遇到麻烦。每次 cpan shell 询问它是否应该遵循依赖项时都启动你的包管理器可能会很累。

通常,另一个缺点是预打包模块的版本。如果您正在运行 Debian 或 Ubuntu,您很快就会发现您将无法生活在最前沿,就像许多 CPAN 模块作者似乎所做的那样。

Linux 上的其他 Perl 人员如何处理这个问题?你只是忽略了你的包管理器必须提供的东西吗?是否有任何工具可以使 apt(例如)和 cpan 成为更好的队友?还是您根本不通过 cpan shell 安装任何东西?

最佳答案

为了开发,我安装了我自己的 Perl 并且不理会系统 Perl。如果我想升级系统 Perl,我使用系统包管理器。对于我的 Perl 开发,我使用 cpan 工具。

由于我将它们分开,我不应该弄乱系统维护任务等所需的 Perl,但我不必依赖系统的开发决策。

安装单独的 Perls 非常容易。当您从源代码分发版运行配置时,它会询问您要将所有内容安装在哪里。给它任何你喜欢的路径。例如,我在 /usr/local/perls 中安装了许多 Perls,并且每个安装的所有内容都单独存在。然后我在 /usr/local/bin 中为它们创建符号链接(symbolic link)(例如 perl5.8.9、perl.5.10.0、perl5.10.0-threaded)。当我想要一个特定版本时,我只使用我想要的那个:

$ perl5.10.0 program.pl

特定的二进制文件可确保程序选择正确的模块搜索路径等(与该二进制文件的 Config.pm 模块中的内容相同)。

这是我用来创建符号链接(symbolic link)的脚本。它在 bin 目录中查找,找出 Perl 版本,并创建 cpan5.10.1 等链接。每个程序都已经知道要调用的正确 perl:

#!perl

use 5.010;

use strict;
use warnings;

use File::Basename;
use File::Spec::Functions;

my $perls_directory = catfile(
    $ARGV[0] // '/usr/local/perls', 
    'perl*'
);
die "$perls_directory does not exist!\n" 
    unless -d dirname $perls_directory;

my $links_directory = $ARGV[1] // catfile( $ENV{HOME}, 'bin' ); #/
die "$links_directory does not exist!\n" unless -d $links_directory;

foreach my $directory ( glob( $perls_directory ) )
{
    say "Processing $directory...";

    unless( -e catfile( $directory, 'bin' ) )
    {
        say "\tNo bin/ directory. Skipping!";
        next;
    }

    my @perls = glob( catfile( $directory, qw( bin perl5* ) ) );    

    my( $perl_version ) = $perls[0] =~ m/(5\.\d+\.\d+)\z/;
    say "\tperl version is $perl_version";

    foreach my $bin ( glob( catfile( $directory, 'bin', '*' ) ) )
    {
        say "\tFound $bin";
        my $basename = basename( $bin );

        my $link_basename = do {
            if( $basename =~ m/5\.\d+\.\d+\z/) { $basename }
            else                               { "$basename$perl_version" }
        };

        my $link = catfile( $links_directory, $link_basename );
        next if -e $link;
        say "\t\tlinking $bin => $link";
        symlink $bin => $link or
            warn "\t\tCould not create symlink [$!]: $bin => $link!";
    }
}

所有东西都安装在特定 Perl 的正确位置。

我也一直在考虑应该将那些 Perl 目录置于某种源代码控制之下。如果我添加了一个我不喜欢的模块,我会退回到较早的版本。不过我才刚刚开始这样做,还没有玩太多。

我在 Effective Perler 博客中写了更多关于这类事情的文章:

  • Make links to per-version tools.
  • Manage your Perl modules with Git.

https://stackoverflow.com/questions/398221/

相关文章:

ruby - Gemfile.lock 写入错误,权限?

linux - 如何将文件从远程服务器复制到本地计算机?

windows - 帮助我让我的 windows cmd.exe 控制台更像一个 Linux 终端

linux - 如何使用 AWK 合并两个文件?

linux - 如何更改某些文件模式/扩展名的权限?

linux - bash 中的线程?

linux - 寻找 Docker 容器进程? (从主持人的角度来看)

linux - PostgreSQL -bash : psql: command not found

linux - 仅当当前行中存在字符串时才替换

linux - 如何在列中格式化控制台输出