目标:我想对来自以下代码中提供的tail
命令的每一行传入数据进行实时模式匹配。
问题:尽管tail
命令和while-loop
正常工作,但随着数据行的进入,似乎没有某种模式匹配。
#!/bin/bash
#
# Description:
#
# Usage:
#
function interval ()
{
echo $(date '+%y%m%d %H%M%S') $cnt
cnt=0
}
declare -i cnt=0
trap interval SIGUSR1
target_file=${1:-access.log)
shopt -s lastpipe
tail -f --pid=$$ ${1:-access.log} | grep --line-buffered "20" | while read aline
do
let cnt++
done < <( grep --line-buffered "20" )
您的问题在这里:
tail -f --pid=$$ ${1:-access.log} | grep --line-buffered "20" | while read aline
do
let cnt++
done < <( grep --line-buffered "20" )
问题:尽管 tail 命令和 while-loop 正常工作,但随着数据行的进入,似乎没有某种模式匹配。
你怎么知道? 很多时候,在 bash 中,找出问题所在的最简单方法是将碎片分开,看看会发生什么。 例如。如果你只运行
tail -f --pid=$$ ${1:-access.log} | grep --line-buffered "20"
您将能够看到传递到 while 循环中的内容。 管道进入 while 循环会将上述命令的输出发送到 while 循环中。 这就是它的输入。 将输入发送到 while 循环的另一种方法是您在此处执行的进程替换:
done < <( grep --line-buffered "20" )
进入 while 循环的管道正在提供输入。 这条线也是。 您只应使用这些方法之一。 但是,此行不执行任何操作,因为它本身需要输入。 如果单独运行该命令,您将看到终端挂起等待您的输入。 尝试在终端上自行运行以下命令:
grep --line-buffered "20"
什么都不会发生。 因此,您使用 2 种方法将输入发送到 while 循环中,并且只应使用一种:
tail -f --pid=$$ ${1:-access.log} | grep --line-buffered "20" | while read aline
do
let cnt++
done
或。。。
while read aline
do
let cnt++
done < <( tail -f --pid=$$ ${1:-access.log} | grep --line-buffered "20" )
当然,有一种更简单的方法可以完成所有这些操作。 您似乎正在尝试将 cnt 变量设置为输出中的行数。 不要使用循环,而是尝试使用 grep 的 -c选项来为您创建行。 将整个内容包装在命令替换中,以将其设置为 cnt 变量:
cnt=$(tail -f --pid=$$ ${1:-access.log} | grep -c --line-buffered "20")