2017-10-07 22 views
-1

如何解析出第二列netstat而不是第一列?如何解析netstat输出并提取第四列

另外,如果连接数低于预期IP数,我该如何使用mailx发送电子邮件警报?

代码

#!/usr/bin/perl 
use strict; 
use warnings; 

my %minimum = (
    '101.101.101.101:2000' => 2, 
    '101.101.101.102:3000' => 5, 
); 

my %count; 

open my $fh, '-|', 'netstat -an' or die "could not run netstat: $!"; 

while(<$fh>) { 
    next unless /^([0-9.]+:\d+000) /; 
    $count{$1}++; 
} 

close $fh; 

while (my ($ip_port, $min) = each %minimum) { 
    $count{$ip_port} ||= 0; 
    next if $count{$ip_port} >= $min; 
    print "$ip_port: need $min connections, found only $count{$ip_port}\n"; 
} 

这里是netstat

tcp 0 0 ::ffff:101.101.101.101:2000 ::ffff:10.151.89.57:8030 ESTABLISHED 

我试图让上面的脚本来看看第四列

ffff:101.101.101.101:2000 

,如果该输出地址不会出现两次然后警报。

10.101.101.102:3000的相同概念在netstat输出的第四列中应该出现不少于五次。

+0

你想拆分你的输入以获得列作为数组。在cpan上还有一个netstat模块。如果您有多个问题,请分开提问。 – simbabque

+0

@simbabque这里是我的netstat环境输出: 'tcp 0 0 :: ffff:101.101.101.101:2000 :: ffff:10.151.89.57:8030 ESTABLISHED'我试图让上面的脚本看看第四栏'ffff:101.101.101.101:2000',如果'101.101.101.101:2000'不退出2次,则警报。 10.101.101.102:3000的相同概念应该从第4列的netstat输出中退出不少于5次 – connollyc4

+0

您所显示的代码中没有任何内容可以访问第四列。请说明你写了什么来解决这个问题。堆栈溢出既不是教程网站,也不是免费获取代码的地方。 – Borodin

回答

0

假设一个单一线和所述列由空格分开,
得到第四列中,使用这样的正则表达式:

/^\s*(?:\S+\s+){3}(\S+)/

^\s*     # BOS 
(?: \S+ \s+){3}  # 3 columns 
(\S+)    # (1), 4th column 

以上是一般形式。
如果你有第4列的具体形式,这将是
这样的

^\s*(?:\S+\s+){3}\S*?([0-9.]+:\d+000)

https://regex101.com/r/IWmbdh/1

+1

太可怕了。 (split)[3]'有什么问题? – Borodin

+0

@Borodin - _horrible_?你怎么知道的 ?什么让你觉得分裂更好?这给出了不同的结果比你的分裂。 – sln

+2

*“我怎么知道?”*我不知道你的意思,但使用正则表达式来实现'split'是非常难以理解的,尤其是因为每个人都阅读它会扫描你的代码十几次试图理解他们错过了什么,因为它*当然*不能只是一个'分裂'。 *“这给出了不同的结果比你的分裂”*除了明显的变化,其结果放在哪里?5 – Borodin

2

如果你问为什么你的代码不能正常工作,这显然因为你将你的正则表达式模式/^([0-9.]+:\d+000) /锚定到字符串的开头。您的示例数据中没有IPv6地址。

请通过编辑添加信息您的问题。这在评论中几乎毫无用处。

下面是我将如何编写代码。有没有理由打开一个管道的句柄

#!/usr/bin/perl 

use strict; 
use warnings 'all'; 

my %minimum = (
    '101.101.101.101:2000' => 2, 
    '101.101.101.102:3000' => 5, 
); 

my %count; 

/\b([0-9.]+:\d+000)\b/ and ++$count{$1} for `netstat -an`; 

while (my ($ip_port, $min) = each %minimum) { 
    my $n = $count{$ip_port} // 0; 
    print "$ip_port: need $min connections, found only $n\n" if $n < $min; 
}