如何检查perl -MCPAN -e的返回值/退出状态?

Bif*_*ost 5 bash perl cpan return-value exit-code

我正在为我的公司编写安装程序,以便我们可以轻松设置新机器.其中一部分是通过各个perl -MCPAN -e 'install "Module::Name"'命令安装的一系列CPAN模块.我创建了一个模块数组(大约200个),它通过bash脚本中的foreach循环安装.但是,我现在想在启动新模块之前检查模块安装的退出状态,这可能吗?这是我到目前为止所尝试的:

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
Run Code Online (Sandbox Code Playgroud)

我也试过以下,没有成功:

perl -MCPAN -e 'install "Madeup::Modulename"'
perl -e 'print $?'
Run Code Online (Sandbox Code Playgroud)

但是,即使模块甚至不存在,它也始终返回0.

任何帮助,将不胜感激.

Thi*_*Not 3

您可以使用该failed命令显示当前会话中失败的所有模块maketest、 或。install不幸的是,failed不返回失败次数,而只是将结果打印到STDOUT.

可能有更好的方法来做到这一点,但使用以下 hack 过滤输出似乎有效:

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/'
Run Code Online (Sandbox Code Playgroud)

(重定向STDOUT到变量的代码取自simbabque对另一个 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)'
Run Code Online (Sandbox Code Playgroud)

当然,如果您正在安装旧版本的模块(并且我不确定开发版本),那么这将不起作用。


如果您愿意尝试不同的安装程序,cpanm实际上会返回正常的值:0 表示成功安装和升级,1 表示未找到或安装失败的模块。