打破 while-read 语句

打破 while-read 语句

我正在编写一个脚本来监视来自几个服务器的日志文件,并在显示某些关键字时发出电子邮件/txt 警报。到目前为止,通过使用以下方法一切都运行良好:

tail -n 0 -f "$MS01_LOG_FILE" "$MS02_LOG_FILE" | while IFS= read -r line; do
#do some fun things here
done

问题是,有时服务器挂起并在相当长的一段时间内没有输出到日志文件,并且我希望收到停止日志的通知。当然,我的脚本将只是坐在读取行等待输入。我需要一种在后台运行的计时器,我想它可以从读取行中断。

答案1

长话短说

下面的替代方案应该可以解决问题:

#!/bin/bash

MS01_LOG_FILE=/var/log/dmesg
MS02_LOG_FILE=/var/log/syslog

TIMEOUT=10  # modify to your liking

tail -n 0 -f "$MS01_LOG_FILE" "$MS02_LOG_FILE" | while :
do
    IFS= read -t $TIMEOUT -r line
    # do your funny things here
done

细节

首先引用自help read(参见内置命令“read”的 bash 参考手册

-t timeout
如果在超时秒内未读取完整的输入行(或指定数量的字符),则导致读取超时并返回失败。 timeout 可以是小数点后带有小数部分的十进制数。仅当 read 正在从终端、管道或其他特殊文件读取输入时,此选项才有效;从常规文件读取时它没有效果。如果读取超时,读取会将读取的任何部分输入保存到指定的变量名称中。如果超时为0,则read立即返回,而不尝试读取数据。如果输入在指定的文件描述符上可用,则退出状态为 0,否则为非零。如果超过超时,则退出状态大于 128。

请注意,在不同的实现之间,无法保证用于检测读取超时的退出状态大于 128(例如,在我的 OS X 的 bash 上,它是 1)。

现在,只需添加-t $TIMEOUT到初始脚本中仅提供了解决方案的一部分,因为只有在尾管发出任何东西后才会检测到损坏的管道。

将 移入read无限 while 循环可以解决该问题。

根据您想要做什么,而不是# do your funny things here您现在可能会面临逃离子进程监狱的问题。

在这种情况下检查https://stackoverflow.com/questions/20558295/quit-from-pipe-in​​-bash

相关内容