我想每次读取一个10000行的大日志文件。我使用这个命令:
tail -c +offset somefile | head -n 10000
我的问题是,通过 head 的管道,tail 会读取整个文件吗?
更新:
我知道tail
将从偏移位置读取。
我想知道的是:
如果文件距离偏移量还剩 20000 行,并且头部只打印前 10000 行,那么尾部会读取剩下的 20000 行吗?或者只阅读前 10000 行?
tail
当它没有读取器时,一旦尝试写入管道,就会因 SIGPIPE 信号而死亡。
所以输出完10000行退出tail
后很快就会死掉。head
因为管道可以保存一些数据(在 Linux 上为 64kiB),并且因为tail
不在终端时缓冲其输出(在我的测试中为 8kiB),并head
以tail
块的形式读取它们的输入(在我的测试中最多为 8kiB),tail
所以可能读取最多 64 +死亡前第 10000 行结束后 8 + 8 kiB offset
。
最坏的情况是head
清空管道的速度比填充管道的速度慢tail
(例如,如果写入终端等慢速输出),并且第 10000 行的最后一个字节位于 8kiB 块的开头。
然后,最终,head
将读取开头带有最后一个换行符的块(比必要的多 8191 个字节),但正忙于写入其输出。tail
,在此期间已填满管道 (64kiB),并读取了另一个 8kiB 块,但由于管道已满,写入被阻止。一旦head
写入最后一行并退出,tail
就会死掉,但会在这 10000 行的最后一行之后读取 64kiB + 8 kiB + 8191 字节。
最好的情况是 10000 行中的最后一行位于 8kiB 块的最末端,并且head
一旦将数据放入管道中就读取数据tail
。然后,如果在最后一个块上,head
设法从管道中读取它并在tail
写入下一个块之前退出,那么tail
它将在写入下一个块时死亡,因此它将仅读取第 10000 行末尾之后的 8192 个字节。
假设somefile
是一个常规文件。somefile
例如,如果某个特殊文件的国王一次滴入一个字节(例如来自 a 的管道while :; do echo; done
),它可能会更快终止