This is a great question: After reading Gilles' answer, I was forced to read man ls
, and ls --help
closely because I was quite sure his answer was wrong. Instead, I offer this answer to prove he is correct! :P
Your result from ls -ls
on a 1024-byte file was:
12 -rw-r--r--. 1 root root 10240 Jul 15 19:22 z
If we believe man ls
, and your assertion that the file in question is 10,240 bytes, then this result tells us that the size of the file is 12 blocks
, but that result does not tell us the size of those blocks. If we refer to the relevant passages from man ls
to learn the block size, we come away empty-handed, more or less.
The relevant passages from man ls
seem to be the following:
--block-size=SIZE
with -l, scale sizes by SIZE when printing them; e.g., '--block size=M'; see SIZE format below
-k, --kibibytes
default to 1024-byte blocks for disk usage; used only with -s and per directory totals
-s, --size
print the allocated size of each file, in blocks
The SIZE argument is an integer and optional unit (example: 10K is 10*1024). Units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers of 1000).
Taking nothing on faith:
Create a 10,240-byte file as follows:
fallocate -l 10240 lstest.txt
Verify:
wc -c lstest.txt
10240 lstest.txt
ls -l
12 -rw-r--r-- 1 pi pi 10240 Jan 4 12:09 lstest.txt
ls -ls
12 -rw-r--r-- 1 pi pi 10240 Jan 4 12:09 lstest.txt
ls -lks
12 -rw-r--r-- 1 pi pi 10240 Jan 4 02:09 lstest.txt
ls -ls --kibibytes
12 -rw-r--r-- 1 pi pi 10240 Jan 4 02:09 lstest.txt
And this seems, as you've said, WEIRD because taking the documentation at face value, 12 * 1,024 = 12,288 bytes - which is greater than 10,240 bytes.
But there's a way out:
Consider three things:
- The
-s
option reports the allocation
not the file size (ref man ls
)
- Block size is an abstraction defined in the file system. It's not a physical quantity, but it's efficient to align the block size with the Advanced Format sector size of 4,096 bytes. All HDDs manufactured since Jan 2011 comply with the Advanced Format standard.
- We can determine the block size of our file system:
stat -fc %s .
# or, if you prefer:
stat -fc %s lstest.txt
# which is, in both cases (on my ext3 filesystem):
4096
Some answers, at last
1. Conclusion from all the above: ls
has no knowledge of the block size used by the file system.
2. If we know the block size, we must share that with ls
to get the correct answer:
ls -ls --block-size=4K
3 -rw-r--r-- 1 pi pi 3 Jan 4 02:09 lstest.txt
Note that 3 * 4,096 = 12,288 bytes. Also note that the block size (4,096 bytes) is a kind of quantum of storage for a block device; i.e. the smallest amount by which a storage allocation can change. It now becomes clear that 12,288 bytes is in fact the required allocation in bytes. However to get the correct answer in blocks, as per man ls
, ls
must be informed of the system's block size via the --block-size=4K
option.
3. Gilles' answer was correct
Ruminations:
It seems to me that man ls
is not as clear as it could be. Perhaps it should be revised to state that it does does not know the file system block size?
Better yet, perhaps ls
could be revised to get the block size from the system? After all - stat
is also part of GNU coreutils 8.30
.