I need some help for this :

Let's say I am in a directory and in this directory there are other directories and files etc...

I would like to use a recursive function to count all the files and directories in it and in the sub too.

I know that I can solve the issue by using wc ... grep or find but I'm really trying to use my first recursive function here.

This is what I have done so far but it doesn't work properly


    for i in $(ls -a $1)
          if [ -d $1/$i ];then
          let d++
          cd $1/$i       
          counting $i
          cd ..
          elif [ -f $1/$i ];then
          let f++


counting $1
echo "number of files = $f ; number of directories = $d"
  • @Theophrastus If you run it in a subshell, the changes to $d and $f won't propagate upwards.
    – n.st
    Oct 24, 2016 at 17:42

1 Answer 1


Here are a few things you can improve (without any claim to completeness):

  1. Never parse the output of ls.
    Your script will break as soon as any file or directory name contains whitespace (which is perfectly legitimate on most modern filesystems).
    Instead use the globbing feature of your shell:

    shopt -s dotglob # to make the * glob match hidden files (like ls -a)
    for i in "$1"/*
  2. Always quote variables.
    Your shell looks at whitespace characters (space, newline, …) to determine where one command argument ends and another starts. Consider the following example:

    filename="foo bar"
    touch $filename
    # gets expanded to `touch foo bar`, so it creates two files named "foo" and "bar"
    touch "$filename"
    # gets expanded to `touch "foo bar`", so it creates a single file named "foo bar"
  3. A cd too many

    cd $1/$i       
    counting $i
    # which in turn calls ...
    ls -a $1

    ls-parsing and unquoted variables aside, this will try to list the contents of the directory ./foo/bar/bar when all you've got is ./foo/bar.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .