2

我试图找出一个命令,使我能够实时读取日志文件并在字符串匹配时执行命令?我正在使用 logkeys 并试图在我输入一个单词时立即触发一个命令。这个脚本有效,但只有当我按下回车(开始换行)时它才会执行,而且我在网上找到的任何东西似乎也需要按下回车键才能工作。有没有办法以某种方式解决这个问题?

#/bin/bash
echo Waiting...
string='test'
tail /path/to/logfile -n0 -f | while read line; do
        if [[ $line =~ $string ]]; then
                echo "hello"
        fi
done
4

1 回答 1

0

我玩过缓冲设置无济于事,所以我的结论是read在完成之前等待换行符。如果您改为read -n1,read将只读取一个字符,这也不是我们想要的,因为 then$line将始终只是那个字符。

不幸的是,grep似乎具有相同的行为(即使更改了缓冲选项),即使grep -o

$ tail logfile -f -n0 | grep -o test &
[1] 25524
$ echo -n test >> logfile
$ echo -n test >> logfile
$ echo test >> logfile
test
test
test

认为一般的解决方案是推出我们自己的“环形缓冲区 grep”搜索工具,将每个字符的字符读入环形缓冲区。

这是我的perl版本,希望对您有所帮助。(另存为ringgrep.pl:)

#!/usr/bin/perl -w

use strict;

if (!$ARGV[0]) {
    print "Usage: $0 needle\n";
    exit 1;
}
my $needle = $ARGV[0];
my $buffer_len = length($needle);
my @buffer = (0) x $buffer_len;
my $i = 0;
my $input;

while(sysread(STDIN, $input, 1)) {
    $buffer[$i] = $input;
    my $string = join("", @buffer);
    $string = (($i+1)%$buffer_len == 0 ? "" : substr($string, $i-$buffer_len+1)) . substr($string, 0, $i+1);
    # print "string is: $string\n";
    if ($string =~ /$needle/) {
        print "got test!\n";
        @buffer = (0) x $buffer_len;
        $i = 0
    } else {
        $i = (++$i) % $buffer_len
    }
}

用法:

$ chmod +x ringgrep.pl
$ tail logfile -n0 -f | ./ringgrep.pl "this is a test" &
[1] 25756
$ echo -n "test" >> logfile
$ echo -n "test" >> logfile
$ echo -n "test" >> logfile
$ echo -n "test" >> logfile
$ echo -n "this is a test" >> logfile
got test!
$ echo -n "this is a test" >> logfile
got test!
$ echo -n "this is a test" >> logfile
got test!
$ (echo -n t; echo -n h; echo -n i; echo -n s; echo -n ' '; echo -n i; echo -n s; echo -n ' '; echo -n a; echo -n ' '; echo -n t; echo -n e; echo -n s; echo -n t) >> logfile
got test!
于 2018-03-25T06:05:48.070 回答