将 tail -f 的输出传递给脚本

将 tail -f 的输出传递给脚本

如果我运行 tail -f /var/log/mail.log 那么它将坐在那里并跟随 (-f) mail.log 当新行添加到文件中时。不幸的是,初始调用导致它打印出最后十行,然后随着文件更改继续添加它们。我最初只是想要最后一行,然后是下一行,在添加时逐行添加。我该怎么做呢?

完成此操作后,我如何将其输出重定向到 Bash Shell 脚本,该脚本获取由 tail -f 生成的每一行并处理其内容以执行“其他操作”?

目前我的“其他事情”是

echo "Finding instances from blockstr.txt"

BLOCKDB=/home/pi/blockstr.txt
IPS=$(grep -Ev "^#" $BLOCKDB)
for i in $IPS
do
   grep $i /var/log/mail.log | grep -v opendkim | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -v '^0' >> block.lst
done
#cat censys.txt >> block.lst
#cat imeas.txt >> block.lst
#cat intcens.txt >> block.lst
#cat iran.txt >> block.lst
iptables -S  | grep DROP | sed 's/^.\{12\}//' | sed 's/.\{11\}$//' > iptab.lst
sort -u block.lst > block.srt
sort -u iptab.lst > iptab.srt
comm -23 block.srt iptab.srt > diff.srt

echo "Blocking IP addresses..."
BLOCKDB=/home/pi/diff.srt
IPS=$(grep -Ev "^#" $BLOCKDB)
for i in $IPS
do
    echo "Adding " $i
    iptables -A INPUT -s $i -j DROP 
done
echo "done."

rm block.lst block.srt iptab.lst iptab.srt diff.srt

如果格式不正确(差不多),我深表歉意,但是对于 blockstr.txt 中的每个字符串,它会逐行扫描 mail.log 查找实例并提取 IP 地址,然后将它们添加到 IPTables 以阻止不法分子。

它的效果正如我所希望的那样,但如果让它在后台不断地这样做就好了。使用 tail -f 唤醒它并给它提供一个新行似乎是一种方法,而不是将其放入 cron 作业并每 1 秒锤击 mail.log 以捕获每秒 60 次尝试登录的白痴。

谢谢你的帮助。

只是为了进一步混淆我最接近的猜测原型将像我所做的管道一样

tail -f (仅一行) /var/log/mail.log | ./blockstrings.sh

答案1

tail默认情况下输出文件的最后十行,但有一个选项-n可以更改它。请求的行数多于文件中的行数并不是错误。

-n选项采用整数行数。无符号或负值从文件末尾开始倒数。显式正值从文件开头开始计数,第一行编号为+1。 (例如,这对于跳过标题行很有用。)

因此tail -n 0 -f myFile将仅显示原始文件的添加内容,并继续等待它们。每秒检查添加内容(也可以选择更改此设置。)

要显示整个原始文件,然后等待任何添加,请使用:

tail -n +1 -f myFile

的某些版本tail还直接接受数字选项,例如tail -5or tail +5,但这是非 POSIX 的。

tail管道的输出将是行缓冲的。但是,无论读取该管道的内容,都可能不会刷新其自己的输出,因此这些结果的输出可能会出现延迟。

相关内容