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

标签 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 {

}

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

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

2018-07-19 xx:11:50,200 fail2ban.actions[3725]: WARNING [iptables] Ban x.x.x.x

我不断收到的错误是:

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.

所有命令都可以从 bash/shell 正常运行,似乎 perl 是否对将 grep 传送到另一个 grep 不满意?我已经尝试了许多不同的方法来将变量 ($ContentDate) 添加到 grep 中而没有帮助。

最佳答案

我注意到您接受的答案有一种相当复杂的方法来计算一个小时前的时间戳,因此我提出了这个替代方案,它以更有效的方式使用 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';
}

但您真正需要的唯一改变是改变:

my $Fail2banNo = `grep Ban /var/log/fail2ban.log | grep $ContentDate | wc -l`;

到:

my $Fail2banNo = `grep Ban /var/log/fail2ban.log | grep "$ContentDate" | wc -l`;

引用 $ContentDate 因为它包含一个空格。

关于linux - 在 Perl 中发送 linux 命令 - Grep 管道到 grep,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51419041/

相关文章:

linux - 安装perl sftp模块时出现问题

linux - 命令行 : search and replace in all filenames matched by grep

regex - Grep 模式匹配-下划线

c - Linux 上的 <conio.h> 头文件在哪里?为什么我找不到 <conio.h>?

linux - 什么时候适合在 GUI 中使用 C++ 智能指针(带有主循环的程序)

c - 在 c 中使用 ntfw 时跳过子目录

perl - Data::GUID 是否生成有效的 GUID?

linux - 将 GAS 与 .intel_syntax 一起使用时出错

perl - perl 中来自 redis 的非阻塞 blpop

linux - 如何使用正则表达式进行 grep 以消除此堆栈跟踪?