Grep-ing 不可搜索的文件

Grep-ing non-seekable file

当使用设备、套接字、管道或 fifos 等不可搜索的文件时,grep 如何为读取行分配缓冲区?

我尝试执行以下操作

grep hello -

我输入了一行,包含大约 9484 个字符,其中包括 space。 Grep 处理了一些字符(我猜是 4K 左右)并将这些字符打印到屏幕上。输入行不包含 hello(我只是重复了行 "One way is to simply treat binary files as text anyway")。没有错误消息,grep 刚刚退出。

grep 应该处理不可搜索的文件吗?如果是这样,它如何管理缓冲区?

编辑:重现它的步骤。 输入

后,我将文本编辑器(sublime text2)中的 9484 个字符复制粘贴到 ubuntu 的终端中
grep hello -

然后我按下control+d结束输入

我无法使用下面提到的 "that other guy" 方式重现它。当我这样做时它似乎有效

while printf "One way is to simply treat binary files as text anyway "; do true; done 2> /dev/null | head -c 9484 | grep hello -

grep,像许多其他 unix 工具一样,基于行工作。也就是说,它永远不必在内存中保留一行以上的内容。有两种处理方法:

  1. (重新)使用单个缓冲区,并在遇到不适合此缓冲区的行时增长。

  2. 类似grep的工具使用readline()函数。

第一种可能效率更高一些,第二种肯定更方便。

如管道示例所示,grep 非常乐意匹配来自不可搜索源的任何长度输入。 GNU grep 特别允许任意行长度。

您遇到的问题是当您粘贴长行时终端的行缓冲区已满。这个缓冲区是 4096 bytes.

您可以在该终端中使用 stty -icanon 禁用行缓冲,然后看到 grep 现在可以愉快地匹配您粘贴的任何行,无论其长度如何。

确保在测试后使用 stty icanonreset 启用,因为行缓冲允许您在大多数 CLI 程序中使用退格键。