通过grep滚动尾部时没有输出

时间:2018-04-07 06:38:56

标签: bash

文件位于$filepath,逐渐增长。我想打印以感叹号开头的每一行:

while read -r line; do 
    if [ -n "$(grep ^! <<< "$line")" ]; then
        echo "$line"
    fi
done < <(tail -F -n +1 "$filepath")

然后,我通过将比较表达式移动到进程替换中来重新安排代码,以使代码更简洁:

while read -r line; do
    echo "$line"
done < <(tail -F -n +1 "$filepath" | grep '^!')
可悲的是,它并没有像预期的那样奏效;没有任何东西打印到终端(标准输出)。

我更喜欢在grep ^\!后写tail。为什么第二个代码段不起作用?为什么将命令管道放入流程替换会使事情变得不同?

PS1。这是我通过随机执行以下命令之一手动生成逐渐增长的文件的方法:

echo ' something' >> "$filepath"
echo '!something' >> "$filepath"

PS2。在GNU bash, version 4.3.48(1)-releasetail (GNU coreutils) 8.25下进行测试。

1 个答案:

答案 0 :(得分:1)

当它的stdout未连接到tty时,

grep不是行缓冲的。所以它试图在生成一些输出之前处理一个块(通常是4 KiB或8 KiB左右)。

您需要告诉grep按行缓冲其输出。如果您使用的是GNU grep,则可以使用:

done < <(tail -F -n +1 "$filepath" | grep '^!' --line-buffered)
                                               ^^^^^^^^^^^^^^^