Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check the return value / exit status of perl -MCPAN -e?

I'm currently writing an installer for my company so we can set up new machines easily. One part of it is a series of CPAN modules that is installed through individual perl -MCPAN -e 'install "Module::Name"' commands. I made an array of the modules (about 200) which is installed through a foreach loop in a bash script. However, I now want to check the exit status of the module installation before starting the new one, is this possible? Here's what I tried so far:

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

I've also tried the following, with no success:

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

However, this always returns 0, even if the module doesn't even exist.

Any help would be appreciated.

like image 638
Bifrost Avatar asked Oct 20 '22 01:10

Bifrost


1 Answers

You can use the failed command to show all the modules that failed to make, test, or install in the current session. Unfortunately, failed doesn't return the number of failures, but simply prints the results to STDOUT.

There is probably a better way to do this, but filtering the output with the following hack seems to work:

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/'

(Code for redirecting STDOUT to a variable taken from simbabque's answer to another SO question)

Note that if a module is not found on CPAN, this will return zero, since it would never even get to the make phase.

You could also use the uptodate command, which returns 1 if the specified module is installed and up-to-date:

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

This won't work, of course, if you're installing older versions of modules (and I'm not sure about development versions).


If you're willing to try a different installer, cpanm actually returns sane values: 0 for successful installs and upgrades, 1 for modules that aren't found or fail to install.

like image 164
ThisSuitIsBlackNot Avatar answered Oct 24 '22 03:10

ThisSuitIsBlackNot