忽略qx的空白变量返回

时间:2013-01-13 17:12:46

标签: regex perl iptables

我的代码有点困难。

open ("files","$list");
while (my $sort = <files>) {
  chomp $sort;
  foreach my $key (sort keys %ips) {
    if ($key =~ $sort) {
      print "key $key\n";
      my $match =qx(iptables -nL | grep $key 2>&1);
      print "Match Results $match\n";
      chomp $match;
      my $banned = $1 if $match =~ (/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/);
      print "Banned Results $banned\n";
      if ($key =~ $banned) {
        print "Already banned $banned\n";
      } else {
        system ("iptables -A INPUT -s $key -j DROP");
        open my $fh, '>>', 'banned.out';
        print "Match Found we need to block it $key\n";
        print $fh "$key:$timestamp\n";
        close $fh;
      }
    }
  }
}

基本上我正在做的是每行打开一个地址列表。

接下来,我将我的密钥变量从我的脚本的另一部分中整理出来,并将其与我的列表匹配,如果匹配则继续执行if语句。

现在使用匹配的密钥我需要检查并查看它是否已被阻止,所以我使用qx来执行iptables和grep for the variable。如果它匹配一切正常。

如果它不匹配,换句话说,我的iptables -nL | grep $key返回一个空白值而不是转到我的else语句,它“抓取”$ match的空白值并继续执行。

对于我的生活,我无法弄清楚如何去除那个空白值并基本上表明它没有回报。

我知道iptables等有模块,但是我必须尽可能保持这个脚本的通用。

2 个答案:

答案 0 :(得分:2)

我建议你使用Perl将iptables -nL的整个输出放入一个数组中grep。这样,您只需调用一次该实用程序,并且很容易检测到空列表。

如果你写

my @iptables = qx(iptables -nL);

在代码的顶部,然后您可以通过

查询此输出
my @match = grep /\b$key\b/, @iptables;

如果没有包含IP地址的记录,则后续

if (@match) { ... }

会失败。

您的代码还有其他一些问题。首先,必须始终 use strictuse warnings在程序开始时,并在所有变量的第一个使用点声明它们。这将发现许多您可能容易忽略的简单错误,尤其适用于您要求代码帮助的情况。

您的open电话应该是

open my $fh, '<', $file or die $!;

一起
while (my $sort = <$fh>) { ... }

而你似乎已经错过了哈希的观点。无需读取哈希中查找匹配项的所有键,因为可以使用$ips{$sort}直接访问哈希元素。如果返回的值为undef,则该元素不存在,或者您可以使用if (exists $ips{$sort}) { ... }显式检查其是否存在。

我无法继续帮助,因为我无法访问提供iptables的平台。如果您需要更多帮助,请从实用程序发布一些输出。

答案 1 :(得分:2)

问题是,当iptables未返回任何结果时,$banned会保留其默认值undef。用作正则表达式,$ banned匹配每个字符串,所以你的条件:

if ($key =~ $banned) {

始终匹配。我认为你打算写的可能是

if ($key eq $banned) {

如果$bannedundef(因为$matched为空或与正则表达式不匹配)或者您使用正则表达式提取的IP地址有所不同,则会失败来自$key

如果您确信iptables结果中的第一个IP与$key相同,那么您可以将条件简化为

if ($match =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/) {