Обновите все модули, установленные local::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 для его обработки).
Возможно ли это, или мне нужно удалить каталог ~/perl5 и переустановить все модули с нуля (возможно, пропустить некоторые, так как я не могу вспомнить их все)?
2 ответа
Обновление: в течение некоторого времени,INSTALL_BASE
создает лучшую структуру каталогов, которая позволяет избежать этой проблемы для новых установок.
И вот почему perl Makefile.PL INSTALL_BASE=...
соглашение (и соответствующий для Build.PL
) используется install::lib отстой.
Удаление (или переименование каталога, чтобы у вас была резервная копия) - самое простое решение. Вы можете узнать, что вы установили, ища .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 в вашей домашней директории.
Если вы используете cpanm
вы можете заставить его перестроить модули в вашем local::lib
местоположение с помощью -L
а также --reinstall
переключатели:
list_modules | cpanm -L ~/perl5 --reinstall
где list_modules
это скрипт, который кормит имена модулей в cpanm
(есть также -f
возможность cpanm
). Этот скрипт может быть похож на @ikegami выше или что-то вроде cpan-outdated
(который только перечисляет устаревшие модули однако). Вот хакерская попытка, которая в основном работала для меня в последнее время (примечание: ikegami, вероятно, лучше) - когда это не удается или скрипт дает 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
запустить "не системный" ("локальный") perl
, Конечно, вы можете сделать это и до сих пор local::lib
, carton
и т. д. управлять каталогом или прикладным стеком модулей.
1). Другой способ сделать обновление - это использовать perllocal
сгенерировать список ваших установленных на данный момент модулей (NB Я не совсем уверен, если perllocal.pod
хранится в надежном / полезном состоянии). [Редактировать: На самом деле perllocal
хранит историю ваших установленных модулей, а не список установленных в данный момент. Вы захотите отфильтровать это, или вы в конечном итоге переустановите всю серию версий модулей одна за другой!). Этот узел perlmonks показывает, как очистить ваш 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
(Примечание: это не проверка ошибок - записи в perllocal.pod
иногда не хватает VERSION
Данные и другие странности, так что будьте осторожны.)
2). Но этот метод бледнеет по сравнению со сценарием оболочки, упомянутым ilmari в #perl-help на IRC. Оно использует jq
- утилита командной строки, которая вам действительно нужна (вы захотите больше после этого). Если вы использовали cpanm
установить ваши модули, которые он создал install.json
файлы. Вы можете использовать это, чтобы составить список для подачи на cpanm
для переустановки текущего набора модулей:
find ~/perl5/ -name install.json -exec jq '.name + "@" + .version' {} +
Очень быстро, очень просто, и вы можете объединить его с cpanm
метод использования curl
для самостоятельной установки, чтобы восстановить ваши модули.
3). Если вы используете perlbrew
для управления вашими установками Perl вы можете легко скопировать и переустановить все ваши модули из одного perl
версия в другую.
НТН!