简体   繁体   English

从perl执行if else shell命令

[英]Executing an if else shell command from perl

I have never run into this scenario before so I could use a little help. 我以前从未遇到过这种情况,因此可以使用一些帮助。 I am trying to issue an if/else statement from a shell command but within perl. 我试图从shell命令但在perl中发出if / else语句。 I've tried system and exec with no success. 我尝试了系统和执行,但没有成功。 Here's a sample of the code 这是代码示例

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";
        }
    }
}

If I run the command if ! dpkg -l curl &> /dev/null; then apt-get install curl -y; fi 如果我运行命令的if ! dpkg -l curl &> /dev/null; then apt-get install curl -y; fi if ! dpkg -l curl &> /dev/null; then apt-get install curl -y; fi if ! dpkg -l curl &> /dev/null; then apt-get install curl -y; fi in shell it works fine but executing it from perl is skips the if part and goes right on to installing it. if ! dpkg -l curl &> /dev/null; then apt-get install curl -y; fi在shell中工作正常,但从perl执行它会跳过if部分,然后继续进行安装。

The if works perfectly fine. if工作完美。

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

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

There is a problem, though. 不过有一个问题。 What you posted is a bash command, but system(EXPR) is short for system('/bin/sh', '-c', EXPR) . 您发布的是一个bash命令,但是system(EXPR)system('/bin/sh', '-c', EXPR)缩写。 Simply replacing 只需更换

system(EXPR)

with

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

should do the trick. 应该可以。

You can avoid getting into the details of if syntax and also simplify it a bit by using || 您可以避免使用if语法的细节,也可以使用||对其进行简化。 instead of negation. 而不是否定。 To try it out on the command line 在命令行上尝试

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

I can only test on RHEL right now thus rpm . 我现在只能在RHEL上测试rpm However, on RHEL I find this to work fine, too 但是,在RHEL上,我也发现它也可以正常工作

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

It is the syntax in the command that conflicts with the shell invoked by system , which is dash on Ubuntu (itself being a link to sh ). 它是命令中的语法,与system调用的shell冲突,在Ubuntu上是dash (它本身是sh的链接)。 Thanks to ikegami and ThisSuitIsBlackNot for comments on this. 感谢ikegamiThisSuitIsBlackNot对此发表评论。 In particular, the redirection &> does not work since that is specifically bash 's feature. 特别是,重定向&>不起作用,因为这是bash的特有功能。 Then you can change to the generic > /dev/null 2>&1 which sends STDOUT stream to /dev/null and redirects STDERR stream (2) to the same place where STDOUT (1) goes 然后,您可以更改为通用> /dev/null 2>&1 ,它将STDOUT流发送到/dev/null并将STDERR流(2)重定向到STDOUT (1)所在的相同位置

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

On a RHEL system the sh is a link to bash , thus &> works. 在RHEL系统上, shbash的链接,因此&>起作用。 Note that the 2&>1 redirection works as well. 请注意, 2&>1重定向也可以。 However, in my opinion a better solution is to specify which shell you want to use. 但是,我认为更好的解决方案是指定要使用的外壳。

The system allows one to not invoke the shell, by supplying arguments in a list. system通过在列表中提供参数来允许调用外壳程序。 Then the program given as the first argument is run directly, without triggering the shell, with the rest of the list being passed to it. 然后,作为第一个参数给出的程序将直接运行,而不会触发外壳,并将列表的其余部分传递给它。 This is the way to get the right shell to run your command, as you can specify that shell as the first argument in the list. 这是使正确的外壳程序运行命令的方法,因为您可以将该外壳程序指定为列表中的第一个参数。 This is shown in the answer by ikegami . 池上的答案就表明了这一点。

The issue seemed a little problematic so I went about another way to solve it. 这个问题似乎有点问题,所以我想出另一种方法来解决它。 Here is what I ended up doing which gives me the same end result 这就是我最终所做的,这给了我相同的最终结果

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";
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM