This is a variant of How does linux manage the offsets of files. Both ls
and du
are correct, they are measuring different things.
When you run truncate
, it reduces the file to 0 bytes. However yes
immediately writes to it again, at the offset following where it had written before; all the missing data is replaced with zeroes, and entirely missing blocks are replaced sparsely. As a result, the apparent size of the file keeps increasing, but the actual disk space it consumes on disk goes back to 0 every time you run truncate
, and while it increases again when yes
writes to it, the sparse blocks aren’t counted.
ls
shows the apparent size of the file by default, whereas du
shows the disk space consumed, so ls
will show a larger value than du
after the first truncate
which loses an entire block. You can get ls
to show the allocated size with the -s
flag.
If you ask the shell to append to yeslog
(yes >> yeslog
), then the file will be opened with O_APPEND
and yes
will write from the beginning of the file after it’s truncated, instead of continuing to write at the same offset as before.