从perl执行if else shell命令

时间:2016-07-26 20:35:23

标签: linux bash perl

我之前从未遇到过这种情况,所以我可以使用一些帮助。我试图从shell命令发出if / else语句但在perl中。我试过系统和exec没有成功。这是代码示例

if ($os eq 'Ubuntu'){
    system('if ! dpkg -l curl &> /dev/null; then apt-get install curl -y; fi');
    foreach my $mod (keys %deb){
        eval "use $mod";
        if($@){
            system("apt-get install $deb{$mod} -y");
            eval "use $mod";
        }
    }
}

如果我在shell中运行命令if ! dpkg -l curl &> /dev/null; then apt-get install curl -y; fi它可以正常工作,但是从perl执行它会跳过if部分并继续安装它。

3 个答案:

答案 0 :(得分:4)

if完美无缺。

$ perl -e'system("if ! true ; then echo ok ; fi")'

$ perl -e'system("if ! false ; then echo ok ; fi")'
ok

但是有一个问题。您发布的是bash命令,但system(EXPR)system('/bin/sh', '-c', EXPR)的缩写。只需更换

system(EXPR)

system('/bin/bash', '-c', EXPR)

应该这样做。

答案 1 :(得分:2)

您可以避免深入了解if语法的详细信息,并使用||而不是否定来简化它。在命令行上试用它

perl -we 'system("rpm -q NO_PACK &> /dev/null || echo \"install package\"")'

我现在只能在RHEL上测试rpm。但是,在RHEL上我发现这也可以正常工作

perl -we 'system("if ! rpm -q NO >& /dev/null ; then echo install; fi")'

命令中的语法与system调用的shell冲突,后者在Ubuntu上是dash(本身是sh的链接)。感谢ikegamiThisSuitIsBlackNot对此提出意见。特别是,重定向&>不起作用,因为它具体是bash的功能。然后,您可以更改为将> /dev/null 2>&1流发送到STDOUT的通用/dev/null,并将STDERR stream(2)重定向到STDOUT(1)的同一位置去

system('dpkg -l curl > /dev/null 2>&1 || apt-get install curl -y');

在RHEL系统上,shbash的链接,因此&>有效。请注意,2&>1重定向也可以。但是,在我看来,更好的解决方案是指定要使用的shell。

system允许一个人通过在列表中提供参数来调用shell。然后直接运行作为第一个参数给出的程序,而不触发shell,并将列表的其余部分传递给它。这是获取正确的shell来运行命令的方法,因为您可以将shell指定为列表中的第一个参数。这在ikegami的答案中显示。

答案 2 :(得分:0)

这个问题似乎有点问题,所以我采用了另一种解决方法。这是我最终做的,它给了我相同的最终结果

if ($os eq 'Ubuntu'){
    my $check = `dpkg --get-selections | grep "^curl *" | awk '{print \$1}'`;
    if(!$check){ system('apt-get install curl -y > /dev/null'); }
        foreach my $mod (keys %deb){
            eval "use $mod";
            if($@){
            system("apt-get install $deb{$mod} -y");
            eval "use $mod";
        }
    }
}