在Perl中发送linux命令 - Grep管道传输到grep

And*_*und 0 linux perl grep command pipe

基本代码:

my $ContentDate = `date -d '1 hour ago' '+%Y-%m-%e %H:'`;
my $Fail2banNo = `grep Ban /var/log/fail2ban.log | grep $ContentDate | wc -l`;

if (($Fail2banNo > $fail2ban)) {

} else {

}
Run Code Online (Sandbox Code Playgroud)

为什么Perl不会正确完成这些命令?$ fail2ban已经定义为0,所以这不是问题.

fail2ban.log确实包含一个应匹配的行(当从shell运行命令时它匹配):

2018-07-19 xx:11:50,200 fail2ban.actions[3725]: WARNING [iptables] Ban x.x.x.x
Run Code Online (Sandbox Code Playgroud)

我一直得到的错误是:

grep: 10:: No such file or directory
sh: -c: line 1: syntax error near unexpected token `|'
sh: -c: line 1: ` | wc -l'
Argument "" isn't numeric in numeric gt (>) at /usr/local/bin/tmgSupervision.pl line 3431.
Run Code Online (Sandbox Code Playgroud)

所有的命令都可以从bash/shell运行得很好,如果perl不满意grep被管道传输给另一个grep?我尝试了很多不同的方法将变量($ ContentDate)添加到grep中而没有帮助.

Dav*_*oss 6

我注意到你接受的答案有一个相当复杂的方法来计算一小时前的时间戳,所以我提出了这个替代方案,它以更有效的方式使用Perl的内置日期和时间处理.

#!/usr/bin/perl

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

use Time::Piece;

my $log = '/var/log/fail2ban.log';
my $fail2ban = 0;

my $ContentDate = localtime(time - 3600)->strftime('%Y-%m-%e %H:');
my $Fail2banNo = qx{grep Ban $log | grep "$ContentDate" | wc -l};

if ($Fail2banNo > $fail2ban) {
  say 'Yes';
}
else {
  say 'No';
}
Run Code Online (Sandbox Code Playgroud)

但实际需要的唯一变化是改变:

my $Fail2banNo = `grep Ban /var/log/fail2ban.log | grep $ContentDate | wc -l`;
Run Code Online (Sandbox Code Playgroud)

至:

my $Fail2banNo = `grep Ban /var/log/fail2ban.log | grep "$ContentDate" | wc -l`;
Run Code Online (Sandbox Code Playgroud)

引用$ContentDate因为它包含空格.