2017-06-20 57 views
-1

我在Perl中重写了一个bash脚本。翻译Bash到Perl

原始脚本检查Linux软件包是否处于未配置的状态,如果是,则删除并重新安装它。

#!/bin/bash 
if [[ $(dpkg -l | grep libc-bin | grep iF) || $(dpkg -l | grep libc-dev-bin | grep iU) ]] ; then 
    echo "do something" 
fi 

我开始看到如果我可以使用系统调用,并将它们存储为变量,然后只需运行这些多个变量的if声明。这似乎没有工作。

#!/usr/bin/perl 

my $libcUnconfigured = system("dpkg -l | grep libc-bin | grep iF"); 
my $libcDevUnconfigured = system("dpkg -l | grep libc-dev-bin | grep iF"); 

if ($libcUnconfigured || $libcDevUnconfigured) { 
    print "Do something"; 
} 
+3

'system'返回返回码,而不是输出。改用'qx //'。 – simbabque

+2

你为什么在Perl中使用grep? – 123

+1

获取软件包列表:'my @libcUnconfigured = grep {/ libc-bin | iF /} qx(dpkg -l)'。 'qx'(“backticks”)返回一个列表,其中'grep'过滤器,你得到一个列表(数组)。 'qx'使用'/ bin/sh'或系统提供的任何内容,因此您可能需要指定命令路径 – zdim

回答

4

为了从外部接收命令输出使用qx operator,不system通过wait作为返回它返回程序的退出状态。

我建议只将外部程序用于在Perl中无法完成的工作,或者很少用于大大简化您的工作。对于所有其他人使用Perl的广泛的处理能力。

在这种情况下list context使用时,这里由grep强加grep

my @libcUnconfigured = grep { /libc-bin|iF/ } qx(dpkg -l); 

print "Do something with $_\n" for @libUnconfigured; 

qx返回行输出列表过滤来自dpkg -l回报。 grep中的代码块在某个元素上运行,每个元素在默认的$_ variable;正则表达式匹配默认在$_上完成。代码评估为true的项目并作为列表返回,此处分配给数组。

请注意,qx使用/bin/sh,它可能会也可能不会被降级到系统上的另一个shell。所以仔细地把命令放在一起。请参阅链接的文档和$? in perlvar进行错误检查。

或者,您可以访问多个模块中的一个。一个很好的一个是Capture::Tiny

use warnings; 
use strict; 
use feature 'say'; 

use Capture::Tiny qw(capture); 

my @cmd = qw(dpkg -l); 

my ($stdout, $stderr) = capture { 
    system (@cmd); 
}; 

warn "Error with @cmd: $stderr" if $stderr; 

say "Do something with $_" for (split /\n/, $stdout); 

以其清晰的语法,它递给我们的错误,并为它的运行几乎任何代码

捕捉能力的事实::微型提供了一个简单,便携捕获几乎所有发送到STDOUT或STDERR的东西,无论它来自Perl,XS代码还是外部程序。

这里的命令形成一个列表,它允许system绕过shell。这样比较好,除非你的需要的shell。在这种情况下的返回是(可能是多行)字符串,因此split用于处理具有包信息的行。

其他一些国家,在提高能力和使用情况的复杂性,是IPC::Run3IPC::Run

另见this entry in perlfaq8。请注意,在一些示例中使用的IPC::Open3是相当低级的。

+0

对一个非常糟糕的问题很好的回答。 –

+0

@CharlesDuffy谢谢你这么说。他们没有把问题归纳起来,这是一种耻辱。这是基本的,但我认为,它会采取多一点合理的做法。 – zdim