Ubuntu – Command ‘ls’ showing directory size instead of block-size

12.0414.04bashcommand line

Is there any ls parameter which I can use to display file-size for directories as well.

When I do ls -s, it shows me block-size(4k always) instead of directory size.

Thank you!!!

Edit – Partial achievement

As told by @Arronical, Command du -sh * shows the files & directories with their size. One small enhancement I am looking is to show directory in different colour like ls shows. Any ideas. Thank you. 🙂

Best Answer

Basic idea

One could emulate the ls -l with find. For instance, like with find command that will run du per each directory and file found:

find . -maxdepth 1  ! -name "."   -printf "%M %u %g "  -exec du -sh  {} \; 2> /dev/null 

Sample output ( side note , here I am using -type d to show listing for directories only for demo purpose; this command without -type d will list all files and directories):

DIR:/xieerqi
skolodya@ubuntu:$ find . -maxdepth 1 -type d ! -name "."   -printf "%M %u %g "  -exec du -sh  {} \; 2> /dev/null | head      
drwxrwxr-x xieerqi xieerqi 348K ./addRemoveDistribution
drwxr-xr-x xieerqi xieerqi 2.2G ./Downloads
drwxrwxr-x xieerqi xieerqi 4.0K ./.screenlayout
drwxr-xr-x xieerqi xieerqi 4.0K ./Public
drwxrwxr-x xieerqi xieerqi 28K  ./Youku Files
drwxrwxr-x xieerqi xieerqi 142M ./.minecraft
drwx------ xieerqi xieerqi 20K  ./.gnupg
drwxrwxr-x xieerqi xieerqi 2.5G ./.Genymobile
drwxrwxr-x xieerqi xieerqi 73M  ./genymotion
drwxrwxr-x xieerqi xieerqi 104K ./scripts

NOTE: find has -ls flag, which I am not using here, for the same reason as OP stated - it shows canonical 4096 bytes

Simplification

This command itself can be turned into an alias, something like ls2 or a function, which then also could take $1 argument. For instance, here's what I've placed into my .bashrc and how it works:

function lscwd
{
 # Function to stat files and folders in current dir
 # Takes first argument as directory to stat
 # If no directory supplied, current dir assumed
 if [ -z "$1" ];then
   DIR="."
 else
   DIR="$1"
 fi

 find "$DIR"  -maxdepth 1 ! -name "."   -printf "%M %u %g "  -exec du -sh  {} \; 2> /dev/null 

}

Sample runs:

DIR:/xieerqi
skolodya@ubuntu:$ lsc
lscpu lscwd 
skolodya@ubuntu:$ lscwd | head                                                                                               
drwxrwxr-x xieerqi xieerqi 348K ./addRemoveDistribution
drwxr-xr-x xieerqi xieerqi 2.2G ./Downloads
drwxrwxr-x xieerqi xieerqi 4.0K ./.screenlayout
drwxr-xr-x xieerqi xieerqi 4.0K ./Public
drwxrwxr-x xieerqi xieerqi 28K  ./Youku Files
drwxrwxr-x xieerqi xieerqi 142M ./.minecraft
drwx------ xieerqi xieerqi 20K  ./.gnupg
drwxrwxr-x xieerqi xieerqi 2.5G ./.Genymobile
drwxrwxr-x xieerqi xieerqi 73M  ./genymotion
drwxrwxr-x xieerqi xieerqi 104K ./scripts

DIR:/xieerqi
skolodya@ubuntu:$ lscwd /etc | head                                                                                          
drwxr-xr-x root root 18M    /etc
drwxr-xr-x root root 68K    /etc/logrotate.d
drwxr-xr-x root root 36K    /etc/apm
drwxr-xr-x root root 96K    /etc/speech-dispatcher
drwxr-xr-x root root 28K    /etc/jwm
drwxr-xr-x root root 8.0K   /etc/hp
drwxr-xr-x root root 8.0K   /etc/gtk-2.0
drwxr-xr-x root root 20K    /etc/gtkmathview
drwxr-xr-x root root 68K    /etc/xml
drwxr-xr-x root root 8.0K   /etc/esound

Output organization

There's no way to colorize the output natively in find, which is designed specifically to parse filenames. ls coloring comes from special characters included into the output, which we don't really want.

However, one could read the permissions. The leading - in -rwxr-xr-x means it's a regular file, and leading d in drwxr-xr-x means directory.

find also has the handy -type flag, which we can use as well to filter the output. For instance, here's edited version of lscwd

function lscwd2
{
 # Function to stat files and folders in current dir
 # Takes first argument as directory to stat
 # If no directory supplied, current dir assumed
 if [ -z "$1" ];then
   DIR="."
 else
   DIR="$1"
 fi

 # print directories first
 printf "*** DIRECTORIES *** \n"
 find "$DIR"  -maxdepth 1 -type d ! -name "."   -printf "%M %u %g "  -exec du -sh  {} \; 2> /dev/null 
 # print non-directories second
 printf "*** FILES *** \n"

 find "$DIR"  -maxdepth 1 ! -type d ! -name "."   -printf "%M %u %g "  -exec du -sh  {} \; 2> /dev/null 
 }

And sample output:

DIR:/bin
skolodya@ubuntu:$ lscwd2
*** DIRECTORIES *** 
drwxrwxr-x xieerqi xieerqi 4.0K ./c
drwxrwxr-x xieerqi xieerqi 12K  ./python
drwxrwxr-x xieerqi xieerqi 12K  ./perl
drwxrwxr-x xieerqi xieerqi 4.0K ./ANOTHERDIR
drwxrwxr-x xieerqi xieerqi 4.0K ./random
drwxrwxr-x xieerqi xieerqi 108K ./sh
drwxrwxr-x xieerqi xieerqi 38M  ./cs2
drwxr-xr-x xieerqi xieerqi 414M ./arduino-1.6.7
drwxrwxr-x xieerqi xieerqi 24K  ./codereview
*** FILES *** 
-rwxrwxr-x xieerqi xieerqi 4.0K ./preventShutdown.sh
-rw-rw-r-- xieerqi xieerqi 4.0K ./Dimmer.desktop
-rwxrwxr-x xieerqi xieerqi 4.0K ./updateWarning.sh
-rw-rw-r-- xieerqi xieerqi 4.0K ./somefile.txt
-rw-r--r-- xieerqi xieerqi 4.0K ./.bashrc
-rwxr-xr-x xieerqi xieerqi 4.0K ./setup.sh
-rwxrwxr-x xieerqi xieerqi 4.0K ./whiledemo.csh
-rwxr-xr-x xieerqi xieerqi 4.0K ./fmtcode.awk
-rwxrwxr-x xieerqi xieerqi 4.0K ./batmon.sh
-rwxr-xr-x xieerqi xieerqi 4.0K ./Dimmer.sh
-rw-rw-r-- xieerqi xieerqi 4.0K ./somefile2.txt

The output sometimes can be very lengthy , so I would suggest using this function in conjunction with less paging utility. Just pipe the output like so lscwd2 | less

About ls and stat

Why do people always suggest du ? izx in his brief and awesome answer explained it way better that I could, but in a nutshell, on Unix and Linux everything is a file, and in the reality directory is a file with a list of files linked to it. Thus, stat and ls give size of that special file, not the total amount of all the files linked to the directory. But du is what saves the day. Note what the description in man du says :

Summarize disk usage of each FILE, recursively for directories.

du utility jumps down into each directory and sums up file size of each file there. Way different from what ls and stat do.

So the purpose of each utility is very different. ls is doing exactly what it is asked to do - list file sizes, and coming from Windows world we understand directory's size as being this "bag" whose size depends on the amount of apples in it, if I may use it for comparison. Unix is slightly different, yes, but it is realistic. Maybe it doesn't cater to user needs that much, but it makes sense in real, physical sense.

On a side note, block size is by default 4k, but once file grows over 4k, the filesystem will need to allocate more space. For instance, my home folder has 73GB in total size of all files there. What about the block size of the directory ?

DIR:/bin
skolodya@ubuntu:$ ls -ld $HOME
drwxr-xr-x 94 xieerqi xieerqi 16384 Jan 22 07:24 /home/xieerqi/
Related Question