How to get the physical size of a file in Linux?

ls -l will give you the apparent size of the file, which is the number of bytes a program would read if it read the file from start to finish. du would give you the size of the file "on disk".

By default, du gives you the size of the file in number of disk blocks, but you may use -h to get a human readable unit instead. See also the manual for du on your system.

Note that with GNU coreutil's du (which is probably what you have on Linux), -b to get bytes implies the --apparent-size option. This is not what you want to use to get number of bytes actually used on disk. Instead, use --block-size=1 or -B 1.

With GNU ls, you may also do ls -s --block-size=1 on the file. This will give the same number as du -B 1 for the file.


$ ls -l file
-rw-r--r--  1 myself wheel  536870912 Apr  8 11:44 file

$ ls -lh file
-rw-r--r--  1 myself wheel   512M Apr  8 11:44 file

$ du -h file
24K    file

$ du -B 1 file
24576   file

$ ls -s --block-size=1 file
24576 file

This means that this is a 512 MB file that takes about 24 KB on disk. It is a sparse file (mostly zeros that are not actually written to disk but represented as logical "holes" in the file). Sparse files are common when working with pre-allocated large files, e.g. disk images for virtual machines or swap files etc. Creating a sparse file is quick, while filling it with zeros is slow (and unnecessary).

See also the manual for fallocate on your Linux system.

I get the file size in bytes like this:

actualsize=$(du -b "${file}" | cut -f 1)