Обновите все модули, установленные локальным:: lib
Я использую local:: lib для обработки установки модулей Perl на сервере, поэтому я могу получить правильные версии для некоторой разработки, не загрязняя установку системы.
Однако системный администратор недавно обновил Perl с 5.16 до 5.18, и теперь я получаю ошибки, связанные с двоичными модулями, например.
perl -e 'use Scalar::Util'
Perl API version v5.16.0 of List::Util does not match v5.18.0 at /usr/lib64/perl5/5.18.2/XSLoader.pm line 92.
Compilation failed in require at /home/paul/perl5/lib/perl5/x86_64-linux/Scalar/Util.pm line 11.
Compilation failed in require at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
Я понимаю, что могу исправить эту проблему, вынудив local:: lib перестраивать все свои модули, но я не могу найти что-либо в документации, которая подсказывает мне, как это сделать, или даже как получить список из всех модулей, которые были установлены с использованием local:: lib (если бы у меня было это в текстовом файле "один модуль в строке", я мог бы легко написать Bash script для его обработки).
Возможно ли это, или мне нужно удалить каталог ~/perl5 и переустановить все модули с нуля (возможно, некоторые из них, поскольку я не могу их запомнить)?
Ответы
Ответ 1
Обновить. В течение некоторого времени INSTALL_BASE
создала лучшую структуру каталогов, которая позволяет избежать этой проблемы для новых установок.
И вот почему соглашение perl Makefile.PL INSTALL_BASE=...
(и соответствующее для Build.PL
), используемое установкой:: lib sucks.
Удаление (или переименование каталога с резервным копированием) является самым простым решением. Вы можете узнать, что вы установили, ища файлы .pm
.
cd ~
mv perl5{,16}
cd perl516/lib/perl5
find -name '*.pm' | xargs perl -MConfig -E'
for (@ARGV) {
s!^\./!!;
s!^5\.\d+\.\d+/!!;
s!^x86_64-linux/!!;
s!^auto/!!;
s!\.pm\z!!;
s!/!::!g;
say;
}
' | xargs cpan
(Сделайте сухой пробег, первый - без задней | xargs cpan
.)
Обратите внимание, что если вы не хотите быть на милости своих обновлений для администратора, вы можете использовать perlbrew
, чтобы легко установить целую сборку Perl в вашем домашнем каталоге.
Ответ 2
Если вы используете cpanm
, вы можете заставить его перестраивать модули в вашем local::lib
месте с помощью переключателей -L
и --reinstall
:
list_modules | cpanm -L ~/perl5 --reinstall
где list_modules
- это script, который передает имена модулей в cpanm
(также опция -f
на cpanm
). Этот script может быть как @ikegami выше или что-то вроде cpan-outdated
(в котором перечислены только устаревшие модули). Вот
хакерская попытка, которая в основном работала для меня в последнее время (примечание: ikegami, вероятно, лучше) - когда он терпит неудачу или script дает cpanm
имя модуля, которое оно не распознает, cpanm
продолжает двигаться и, похоже, не разбивается ничего (но делать резервные копии):
cd $PERL_LOCAL_LIB_ROOT
perl -MFile::Find -MConfig -E'
find {
wanted => sub {
$mod = $_ if /\.pm\z/;
$mod =~ s/lib\/perl5\/auto\/.*//g;
$mod =~ s/lib\/perl5\/\Q$Config{archname}\E\/.*//g;
$mod =~ s/lib\/perl5\///g;
push @mods, $mod unless $mod =~ /^$/;
},no_chdir=>1
},"lib/perl5"; @modhash{@mods}=(); say for sort keys %modhash '
Изменяя, где и что File::Find
находит с помощью wanted()
, вы можете подать другой список модулей на cpanm
. Было бы неплохо, если бы cpan
или cpanm
имели внутренний _method
или -switch
, который позволял вам принудительно восстановить local::lib
установленные модули, которые используют XS. Есть ли такая вещь?
Это было cpanm
, carton
(и видя инструмент node.js
npm
в действии), что побудило меня сделать гораздо больше local::lib
. Теперь CORE в комплекте "клиент CPAN", который поставляется с perl (cpan
), кажется, становится более автоматическим и более простым в использовании. Мне очень нравится local::lib
, поскольку он позволяет использовать систему perl
, но управлять собственным стеком модулей без привилегий системного уровня. Однако проще управлять изменениями и обновлениями, если вы используете perlbrew
для запуска "несистема" ( "local" ) perl
. Конечно, вы можете сделать это , а все еще есть local::lib
, carton
и т.д. Управлять каталогом или конкретным стеком модулей.
1). Другой способ сделать обновление - использовать perllocal
для создания списка ваших установленных модулей ( NB. Я не совсем уверен, что perllocal.pod
хранится в надежном/полезном состоянии). [Изменить: Фактически perllocal
хранит историю ваших установленных модулей, а не список установленных в настоящее время. Вы захотите отфильтровать это, иначе вы сможете переустановить всю серию версий модулей один за другим!). Этот perlmonks node показывает, как очистить ваш perllocal.pod
: http://www.perlmonks.org/?node_id=483020. Я предпочитаю сохранить историю. ]
Чтобы выполнить синтаксический анализ perllocal.pod
для ввода в cpanm
, выполните поиск по файлу и сохраните совпадения в массиве, а затем разделите их на два, чтобы создать хэш из элементов массива (key,value,key,value
). Более поздние установки и номера версий в файле ниже, поэтому вы можете создать хэш с именами модулей в качестве ключей и обновить значения более поздними записями:
perl -ne 'push @arr, grep {defined}
(/\A=head2.*:\s+C<Module>\s+L<(.*)\||.*C<VERSION:\s(.*)>\Z/msx); }{
%h = map{ split/,/,$_,2 } @arr; print "$_\@$h{$_}\n" for keys %h' perllocal.pod
(NB: это не проверка ошибок - записи в perllocal.pod
иногда отсутствуют VERSION
данные и другие странности, поэтому будьте осторожны.)
2). Но этот метод бледнеет по сравнению с оболочкой script, указанной ilmari в # perl-help на IRC. Оно использует
jq
- утилита командной строки, которая вам действительно нужна (после этого вы захотите ее больше). Если вы использовали cpanm
для установки своих модулей, он создал файлы install.json
. Вы можете использовать это, чтобы сделать список для подачи на cpanm
для переустановки текущего набора модулей:
find ~/perl5/ -name install.json -exec jq '.name + "@" + .version' {} +
Очень быстро, очень просто, и вы можете объединить его с методом cpanm
использования curl
для самостоятельной установки, чтобы перестроить ваши модули.
3). Если вы используете perlbrew
для управления установками perl, вы можете легко скопировать и переустановить все ваши модули из одной версии perl
в другую.
НТН!