`ls -lS` isn't showing true size of directory

ls -lS is indeed showing the true size of the directory: the directory itself + references to any file contained in the given directory.

You could use du instead of ls:

du -h --max-depth=1 | sort -hr

du: estimates file space usage recursively for directories

h: human readable

--max-depth=1: so you only check for the directories within the current directory

sort -hr: sorts it decreasingly


ls shows the size of the regular files (or, in case of directories, the size of its inodes, not just their content, as it has no quick way to determine that, whereas for regular files the size is known and thus can be displayed exactly and quickly).

Actually that field differs depending on what the file represents :

  • for regular files : it shows their actual size
  • for symlinks (symbolic links, ln -s source dest) : the length of the symlink name (as this the content of the symlink file). (ex: the symlink /dev/fd -> /proc/self/fd : has a destination path exactly 13 caracters long ( / p r o c / s e l f / f d ), so ls -l will display "13" in the 5th column, instead of the size of the pointed-at file.)
  • for directories: the size of an inode (if the content of the directory entries fits into one) or multiple inodes (if there was a need for multiple inodes to describe the list of that directory's entries). This is why you see 4096 for most of them : usually they don't have many files inside them so it fits all into 1 inode, which is usually 4096 bytes per default. If you ever put MANY files in some directory, this will go up (and most likely will stay up afterwards, unless you recreate the directory itself).
  • for pipes, and other files types : each time the field usually associated with size may or may not be a size (ex: for block-devices (ex: /dev/hd* files ) it doesn't show any size but instead shows their major, minor pair of information. See man mknod. See man ls to see how they are identified as well.)

To know the sum of content of directories + subdirs:

  • du /some/path # will show for each directory : the sum of its content (including subdirs), and shows that for every directory at and underneath /some/path

  • du -s /some/path # will show only 1 level, ie just the total for /some/path

  • du -S /some/path # show the content of each dir, not including their subdirs. Usefull to know exactly which of the subdir of /some/path are big.

See https://linux.die.net/man/1/du for more details.

Tags:

Directory

Ls