如何(头部;尾部)文件工作?注意cat文件| (头;尾)不。
注意:我理解头和尾如何工作。只是不是涉及这些特定的调用的微妙。
对于OS X,您可以查看source code for head
和source code for tail
来了解一些发生了什么。在tail的情况下,你会想看forward.c。
所以,事实证明,头不做任何特别的。它只是使用stdio库读取其输入,所以它一次读取一个缓冲区,可能读得太多。这意味着cat文件| (head; tail)不适用于小文件,其中head的缓冲使得它读取最后10行的一些(或全部)。
另一方面,tail检查其输入文件的类型。如果它是一个常规文件,尾部寻找到结束并向后读取,直到找到足够的行发射。这就是为什么(头;尾)文件适用于任何常规文件,无论大小。
Linux
你可以在Linux上查看head和tail的源代码,但是更容易使用strace,像这样:
(strace -o /tmp/head.trace head; strace -o /tmp/tail.trace tail) < file
看看/tmp/head.trace。你会看到head命令通过从标准输入(文件描述符0)读取来填充一个缓冲区(在我的测试中为8192字节)。根据文件的大小,它可能或可能不会填充缓冲区。无论如何,让我们假设它在第一次读取中读取10行。然后,它使用lseek将文件描述符备份到第10行的末尾,本质上是“读取”它读取的任何额外字节。这是因为文件描述符在正常的可搜索文件上打开。所以(头;尾)文件将工作任何可寻找的文件,但它不会使猫文件| (头;尾)工作。
另一方面,tail不(在我的测试中)寻找到结束和向后读,就像它在OS X上。至少,它不会一直读回文件的开头。
这是我的测试。创建一个小的,12行的输入文件:
yes | head -12 | cat -n > /tmp/file
然后,尝试(头部;尾部) / tmp / file。我得到这与GNU coreutils 5.97:
1 y 2 y 3 y 4 y 5 y 6 y 7 y 8 y 9 y 10 y 11 y 12 y
但在OS X上,我得到这个:
1 y 2 y 3 y 4 y 5 y 6 y 7 y 8 y 9 y 10 y 3 y 4 y 5 y 6 y 7 y 8 y 9 y 10 y 11 y 12 y