head
по умолчанию печатает 10 строк, но при этом считывает как можно больше вводимых данных - обратите внимание, что GNU head
имеет параметры, которые требуют, чтобы он знал, сколько всего строк в файле, поэтому чтение как можно большего количества не является неправильным.
head
читает столько, сколько может, чтобы заполнить свой буфер, который, кажется, составляет 8192 байта:
~ seq 10000 | strace -fe read ./foo.sh
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260e\1\0\0\0\0\0"..., 832) = 832
...
Process 17610 attached
...
[pid 17610] read(0, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14"..., 8192) = 8192
...
[pid 17611] read(0, "\n1861\n1862\n1863\n1864\n1865\n1866\n1"..., 8192) = 8192
...
Поскольку первые две записи составляют 4096 байтов каждая, они могут быть использованы первой головкой
.
Это зависит от времени. Если seq
удалось получить только одну запись
к тому времени, когда первая голова
напечатала 10 строк и завершилась, то вторая запись
будет взять на себя вторую голову
.
комментарий от mikeserv проясняет:
вы должны попробовать его с обычным файлом.
seq 10000> / tmp / nums; yourscript tmp / nums
Причина, по которой это ведет себя так, как и следовало ожидать, заключается в том, что head
пытается переместить текущую точку чтения в строку после тех, которые она выводила, используя lseek ()
. Это работает для обычных файлов, перенаправленных файлов и т. Д., Но не работает для каналов:
The lseek() function shall fail if:
...
ESPIPE The fildes argument is associated with a pipe, FIFO, or socket.
Как видно из strace
:
~ seq 10000 | strace -fe lseek ./foo.sh
...
Process 18561 attached
[pid 18561] lseek(0, -8171, SEEK_CUR) = -1 ESPIPE (Illegal seek)
[pid 18561] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=18561, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
Process 18562 attached
[pid 18562] lseek(0, -8146, SEEK_CUR) = -1 ESPIPE (Illegal seek)
...