[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#33281: head does not consume input after '-c' is satisfied
From: |
Bernhard Voelker |
Subject: |
bug#33281: head does not consume input after '-c' is satisfied |
Date: |
Tue, 6 Nov 2018 08:06:38 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 |
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