超时后终止tail命令

时间:2017-04-07 20:46:51

标签: bash shell

我正在使用tail -f file_name在文件中捕获 stdout (日志)以保存具有grepsed的特定字符串(退出尾部) :

tail -f log.txt | sed /'INFO'/q |  grep 'INFO' > info_file.txt

这样可以正常工作,但我希望终止命令,以防它在一段时间后在日志文件中找不到模式(INFO

我想要这样的东西(不起作用)在超时(60秒)后退出脚本:

tail -f log.txt | sed /'INFO'/q |  grep 'INFO' | read -t 60

有什么建议吗?

3 个答案:

答案 0 :(得分:3)

因为您只想捕获一行:

#!/bin/bash
IFS= read -r -t 60 line < <(tail -f log.txt | awk '/INFO/ { print; exit; }')
printf '%s\n' "$line" >info_file.txt

对于更一般的情况,您想要捕获多行,以下不使用tail以外的其他外部命令:

#!/usr/bin/env bash
end_time=$(( SECONDS + 60 ))
while (( SECONDS < end_time )); do
  IFS= read -t 1 -r line && [[ $line = *INFO* ]] && printf '%s\n' "$line"
done < <(tail -f log.txt)

一些注意事项:

  • SECONDS是bash中的内置变量,读取后将检索自shell启动以来的秒数。 (它在成为任何赋值的目标后失去了这种行为 - 避免此类错误是POSIX variable-naming conventions为应用程序使用保留小写字符的名称有用的部分原因。
  • (( ))创建算术上下文;其中的所有内容都被视为整数数学。
  • <( )流程替换;它计算类似文件的对象(命名管道,/dev/fd引用或类似物)的名称,当读取时,它将包含其中包含的命令的输出。请参阅BashFAQ #24,了解为什么这比管道read更合适。

答案 1 :(得分:2)

这似乎对我有用......

read -t 60 < <(tail -f log.txt | sed /'INFO'/q | grep 'INFO')

答案 2 :(得分:1)

timeout命令( Debian / Ubuntu “coreutils”包的一部分)似乎合适:

timeout 1m tail -f log.txt | grep 'INFO'