【问题标题】:No output while piping tail through grep [duplicate]通过grep管道尾部时没有输出[重复]
【发布时间】:2018-04-07 06:38:55
【问题描述】:

有一个位于$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 '^!')

很遗憾,它没有按预期工作;没有任何内容打印到终端(标准输出)。

我更喜欢在tail 之后写grep ^\!。为什么第二个代码 sn-p 不起作用?为什么将命令管道放入进程替换中会有所不同?

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

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

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

【问题讨论】:

  • @iBug 哇。感谢您的反馈。我仔细地重新尝试了上面的代码,它仍然有效。我在 Ubuntu 16.04 上使用版本 4.3.48(1)-release 的 GNU Bash。
  • 第二版,你可以试试grep --line-bufferedstackoverflow.com/questions/13858912/…
  • @Sundeep 谢谢。您的评论明显早于 iBug 的帖子。
  • 难以置信......它实际上与tail -F无关,这让我困惑了一段时间,然后才弄清楚这是grep的错。
  • @Sundeep 你打败了我。事实证明,您的评论是正确答案。

标签: bash


【解决方案1】:

grep 在其标准输出未连接到 tty 时不进行行缓冲。所以它会在生成一些输出之前尝试处理一个块(通常是 4 KiB 或 8 KiB 左右)。

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

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

【讨论】:

    猜你喜欢
    • 2012-12-01
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多