我正在使用tail -f file_name
在文件中捕获 stdout (日志)以保存具有grep
和sed
的特定字符串(退出尾部) :
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
有什么建议吗?
答案 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'