GNU bug report logs -
#33281
head does not consume input after '-c' is satisfied
Previous Next
Full log
View this message in rfc822 format
On 11/5/18 10:17 PM, Philip Rowlands wrote:
> On Mon, 5 Nov 2018, at 20:30, Luiz Angelo Daros de Luca wrote:
>>
>> Once head read enough bytes to satisfy -c option, it stops reading input
>> and quit.
>> This is different from what -n does and it is also different from both
>> FreeBSD and busybox head implementation.
>>
>> With GNU Coreutils head:
>>
>> $ echo -e "123\n456\n789" | { head -n 1; while read a; do echo "-$a-";
>> done; }
>> 123
>
> This is incomplete; head doesn't read everything, but more than one line. On my (rather aged Linux) system:
> $ head --version
> head (GNU coreutils) 8.25
>
> $ seq 1864 | { head -n 1; while read a; do echo "-$a-"; done; }
> 1
> --
> -1861-
> -1862-
> -1863-
> -1864-
>
> What's special about 1860 lines of output? It's just over the amount of data which head reads from the pipe, 8192 bytes.
Indeed, running 'head' via 'strace' seconds that:
read(0, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14"..., 8192) = 8192
... and: 'head' tries to "undo" the reading by calling lseek(),
but that typically fails as stdin is a pipe:
lseek(0, -8190, SEEK_CUR) = -1 ESPIPE (Illegal seek)
Thus said, if your input was a regular file, then this positioning back to
where the newline "\n" was would succeed:
$ file=$(mktemp) \
&& seq 4 > "$file" \
&& { strace -ve read,lseek head -n 1; while read a; do echo "-$a-"; done; } < "$file" \
; rm -f "$file"
...
read(0, "1\n2\n3\n4\n", 8192) = 8
lseek(0, -6, SEEK_CUR) = 2
1
+++ exited with 0 +++
-2-
-3-
-4-
Have a nice day,
Berny
This bug report was last modified 6 years and 235 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.