2014-09-15 4 views
4

В настоящее время я пишу установщик для своей компании, чтобы мы могли легко создавать новые машины. Одна из них - это серия модулей CPAN, которые устанавливаются через отдельные команды perl -MCPAN -e 'install "Module::Name"'. Я создал массив модулей (около 200), который устанавливается через цикл foreach в сценарии bash. Однако теперь я хочу проверить статус выхода установки модуля перед запуском нового, возможно ли это? Вот что я пытался до сих пор:Как проверить статус возвращаемого значения/выхода perl -MCPAN -e?

for i in "${CPANmodules[@]}" 
do 
    echo -e "\033[1;32mInstalling CPAN module $i \033[0m" 
    perl -MCPAN -e "install \"$i\"" 
    if [ $? -ne 0 ] 
    then 
     echo "Error installing module $i" 
    fi 
done 

Я также попытался следующие, но безуспешно:

perl -MCPAN -e 'install "Madeup::Modulename"' 
perl -e 'print $?' 

Однако это всегда возвращает 0, даже если модуль даже не существует.

Любая помощь будет оценена по достоинству.

+1

Просто догадайтесь: можете ли вы установить 'Makeup :: Modulename 'или выйти 1''? –

+0

Отличное предложение, однако, ничего не меняет. – Bifrost

+0

Быстрый тест здесь с предложением от @TomFenech работал на моей машине CentOS 5 (после того, как я прошел через настройку CPAN, поскольку раньше не использовал ее на этой машине). –

ответ

2

Вы можете использовать команду failed, чтобы показать все модули, которые не удалось make, test или install в текущей сессии. К сожалению, failed не возвращает количество отказов, а просто выводит результаты на STDOUT.

Существует, вероятно, лучший способ сделать это, но фильтрация выходного сигнала с помощью следующего хака, кажется, работает:

perl -MCPAN -wE ' 
    CPAN::Shell->install("Foo::Bar"); 
    open my $buffer, ">", \my $failed or die $!; 
    my $stdout = select $buffer; 
    CPAN::Shell->failed; 
    select $stdout; 
    close $buffer; 
    exit 1 unless $failed =~ /Nothing failed in this session/' 

(код для перенаправления STDOUT переменный, взятых из simbabque's answer в другой SO вопрос)

Обратите внимание, что если модуль не найден в CPAN, он будет возвращать ноль, так как он никогда не достигнет фазы make.

Вы также можете использовать uptodate команду, которая возвращает 1, если установлен указанный модуль и уточненный:

perl -MCPAN -wE ' 
    $name = "Foo::Bar"; 
    CPAN::Shell->install($name); 
    $mod = CPAN::Shell->expandany($name); 
    exit(! defined $mod || ! $mod->uptodate)' 

Это не будет работать, конечно, если вы устанавливаете старше версии модулей (и я не уверен в версиях разработки).


Если вы готовы попробовать другой инсталлятор, cpanm фактически возвращает здравомыслящее значение: 0 для успешных установок и обновлений, 1 для модулей, которые не встречаются или не в состоянии установить.

+0

Спасибо за ваш ответ. Думаю, мне нужно переключиться на cpanm, если я хочу использовать те функции, которые я намеревался сделать. – Bifrost

+0

@Bifrost Лично, я * предпочитаю * 'cpanm', потому что по умолчанию он намного менее подробный, чем' cpan'. – ThisSuitIsBlackNot

0

Используйте эту форму CPAN метод установки

sudo perl -MCPAN -e 'CPAN::Shell->install("Devel::Cover") or exit 18' 
+1

Редактировать: Это всегда возвращает 18. Попробовал это с именем makeup, уже установленным модулем и еще не установлен (но был успешно установлен). Все возвращено 18. – Bifrost

+0

Отредактировано моим предыдущим комментарием. Спасибо за ваш ответ. – Bifrost