将Bash翻译为Perl

时间:2017-06-20 17:31:32

标签: bash perl if-statement conditional system

我正在重写Perl中的bash脚本。

原始脚本检查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";
}

1 个答案:

答案 0 :(得分:4)

要从外部命令接收输出,请使用qx operator,而不是system,它返回wait返回的程序退出状态。

我建议只将外部程序用于Perl中无法做到的事情,或者很少,当它们大大简化您的工作时。对于其他所有使用Perl的广泛处理能力。

在这种情况下,按grep

过滤dpkg -l的回复
my @libcUnconfigured = grep { /libc-bin|iF/ } qx(dpkg -l);

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

qxlist context中使用时会返回输出行列表,此处由grep强制执行。 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);

因为它的语法干净,它将错误交给我们,并且能够运行几乎任何代码

  

Capture :: Tiny提供了一种简单,可移植的方式来捕获发送到STDOUT或STDERR的几乎任何内容,无论它是来自Perl,来自XS代码还是来自外部程序。

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

其他一些人,在使用能力和使用复杂性方面,IPC::Run3IPC::Run

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